Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

Array flattening is the process of converting a multi-layer nested array (multidimensional array) into a single-layer array (one-dimensional array). This is a hot topic in the interview process and will be used occasionally during the development process

So now I have this array

const arr = [1.2[3[4.5]], 6[7.8]].Copy the code

Implement a function flatten to flatten it

flat

Array flattening can be implemented directly by calling the flat method in ES6, which is an officially provided API

The Flat () method recurses through the array of numbers at a specified depth and returns all the elements in a new array combined with the elements in the traversed subarray.

Usage:

var newArray = arr.flat([depth]);
Copy the code

Depth: Specifies the structure depth of the nested array to be extracted. If this is not specified, the default value is 1. When Infinity is specified, both layers flatten to one

arr.flat(Infinity)
Copy the code

The ⚠️ : flat() method removes empty items from the array

const arr = [1,,3.4]];
arr.flat(Infinity); / / [1, 3, 4]
Copy the code

Ordinary recursive

Recursion should be one of the first implementations that comes to mind. Recursion can always solve many problems unpretentiously 😂

const flatten = (arr) = > {
  let res = [];

  for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if (Array.isArray(item)) {
      // If it is an arrayres = res.concat(... flatten(item)); }else {
      // Non-array direct pushres.push(item); }}return res;
};
Copy the code

The above is the way through the loop recursion, one item by one to traverse, if each item is still an array, then continue to traverse, the use of recursive procedures, to achieve the array of each item join

Recursive + reduce

Use reduce to replace redundant judgments in normal recursion

const flatten = (arr) = > {
  return arr.reduce((res, item) = > {
    return Array.isArray(item) ? res.concat(... flatten(item)) : res.concat(item) }, []); };Copy the code

The overall code is much simpler, simplifying the for loop and if condition judgment, but the overall idea and simple recursion remain the same

while + some

const flatten = (arr) = > {
  while (arr.some((item) = > Array.isArray(item))) { arr = [].concat(... arr); }return arr;
};
Copy the code

The overall idea: loop continuously through while, and the end condition is that the entire array becomes a one-dimensional array. The loop condition is always true as long as there is a multidimensional array

The some function checks for the presence of multidimensional arrays

The while is used internally to continuously flatten data layer by layer

So the while loop ends, and the array is the one-dimensional array that we want

While + stack

Comments in the core process reference code

const flatten = (arr) = > {
    const stack = [...arr];
    const res = [];
    while (stack.length) {
        // Use pop to fetch and remove values from the stack
        const next = stack.pop();
        if (Array.isArray(next)) {
            // Use push to send back elements in the inner array without changing the original inputstack.push(... next); }else{ res.push(next); }}// Reverse the order of restoring the original array
    return res.reverse();
};
Copy the code

toString + split

The array toString

const str = arr.toString(); / / 1,2,3,4,5,32,6,7,8
Copy the code

Split the resulting string split into an array with, split

str.split(', '); // ['1', '2', '3', '4', '5', '32', '6', '7', '8']
Copy the code

The two resume apis enable array flattening

Generator

Using the Generator feature

const flatten = function* (arr) {
    for (const item of arr) {
        if (Array.isArray(item)) {
            yield* flatten(item);
        } else {
            yielditem; }}};console.log([...flatten(arr)]);
Copy the code

Reg + JSON

const flatten = (arr) = > {
  let str = JSON.stringify(arr);
  str = str.replace(/(\[|\])/g.' ');
  str = '[' + str + '] ';
  return JSON.parse(str); 
};
Copy the code

Overall idea:

  1. First serialize the array to get a string
  2. Use the re to serialize the string[and]All replacement
  3. Manual stitching[], deserialized to a flattened array