Implement Array.prototype.flat()

Array.prototype.flat

Array.prototype.flat is a common question both in interviews and in work, so let's implement it!

First, we can create the myflat method, its API definition is as follows:

Array.prototype.myflat = function (depth) {
// ...
};

depth represents the number of levels to flatten, and it defaults to flattening completely.

Now, we have an array [1, 2, [3, 4, [5, 6]]] and the following examples show the results of flattening by 1 level, 2 levels, and completely:

const arr = [1, 2, [3, 4, [5, [6]]]];
arr.myflat(1); // [1, 2, 3, 4, [5, [6]]]
arr.myflat(2); // [1, 2, 3, 4, 5, [6]]
arr.myflat(); // [1, 2, 3, 4, 5, 6]

If no parameters are passed in, it means to flatten completely. If a parameter is passed in, it represents the number of levels to flatten.

Implementation

Method 1, using recursion

Array.prototype.myflat = function (depth) {
const result = [];
this.forEach((arr) => {
if (Array.isArray(arr) && depth !== 0) {
result.push(...arr.myflat(typeof depth === 'number' ? depth - 1 : undefined));
} else {
result.push(arr);
}
});
return result;
};

The most important thing about recursion is the base case. When we encounter a value that is not an array or when the depth is 0, it means we have reached the deepest level, so we can simply return the value directly.

You can imagine that in each recursion, we are expanding the array. For example, [1, 2, [3, 4, [5, [6]]]], after fully expanding, it would become:

const result = [];
result.push(...[1, 2, ...[3, 4, ...[5, ...[6]]]]);
console.log(result); // [1, 2, 3, 4, 5, 6]

Method 2, using reduce

The concept is the same as Method 1, but it's implemented using reduce.

Array.prototype.myflat = function (depth) {
return this.reduce((result, arr) => {
if (Array.isArray(arr) && depth !== 0) {
return [...result, ...arr.myflat(typeof depth === 'number' ? depth - 1 : undefined)];
} else {
return [...result, arr];
}
}, []);
};

Summary

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

Array.prototype.myflat = function (depth) {
  const result = [];

  this.forEach((arr) => {
    if (Array.isArray(arr) && depth !== 0) {
      result.push(...arr.myflat(typeof depth === 'number' ? depth - 1 : undefined));
    } else {
      result.push(arr);
    }
  });

  return result;
};

// Array.prototype.myflat = function (depth) {
//  return this.reduce((result, arr) => {
//    if (Array.isArray(arr) && depth !== 0) {
//      return [...result, ...arr.myflat(typeof depth === 'number' ? depth - 1 : undefined)];
//    } else {
//      return [...result, arr];
//    }
//  }, []);
//};

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');
  res.end(`${JSON.stringify([1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]].myflat())}`);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

The above demonstrations are conceptual. Please use the built-in Array.prototype.flat in daily development!

References

  1. Leetcode 2625. Flatten Array
  2. bigfrontend.dev

Categories