How to Flatten a Multidimensional Array in JavaScript?

Learn how to flatten a deep nested array in JavaScript

In this article, we will look at ways to flatten a deep nested array. For all topics in this article, we'll be using the following nested array of objects as an example:

const users = [
    [{ id: 1, name: 'John' }, { id: 3, name: 'Wayne' }],
    [ [{ id: 7, name: 'Melissa' }, { id: 2, name: 'David' }] ],
];

As you can see in the array above, the first element is only one-level deep, while the second element is two-levels deep. The following topics show how we can flatten elements of an array in either of those cases:

Using Array.flat()

In ES2019+, we can make use of the flat() function to flatten an array one-level deep like so:

// ES2019+
const flattened = users.flat();

console.log(flattened);

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    [ { id: 7, name: 'Melissa' }, { id: 2, name: 'David' } ],
] */

Flatten Deep Nested Array:

We can also specify the depth level to the flat() function by passing it as an argument (which defaults to 1). Using the depth argument, we can specify how deep a nested array structure should be flattened. For example:

// ES2019+
const flattened = users.flat(4); // flatten array 4-levels deep

console.log(flattened);

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    { id: 7, name: 'Melissa' },
    { id: 2, name: 'David' },
] */

Using the Spread Operator With Array.concat()

We can use the spread operator with concat() to flatten an array one-level deep, like so:

// ES6+
const flattened = [].concat(...users);

// or
const flattened = Array.prototype.concat(...users);

console.log(flattened);

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    [ { id: 7, name: 'Melissa' }, { id: 2, name: 'David' } ],
] */

Flatten Deep Nested Array:

To flatten a deep nested array, we could modify our code to recursively flatten the array, like so:

// ES6+
const flatten = arr => Array.isArray(arr) ? [].concat(...arr.map(flatten)) : arr;

console.log(flatten(users));

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    { id: 7, name: 'Melissa' },
    { id: 2, name: 'David' },
] */

Using Array.concat() With apply()

The ES5, equivalent of using the spread operator with concat() (to flatten an array one-level deep) would be:

// ES5+
const flattened = [].concat.apply([], users);

console.log(flattened);

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    [ { id: 7, name: 'Melissa' }, { id: 2, name: 'David' } ],
] */

Using apply():

  1. The first argument changes the this value of the concat() function to an array;
  2. The second argument passes each element of the array as a series of arguments for concat(). This works because concat() accepts any number of arrays/values as argument (which it concatenates into a new array).

Flatten Deep Nested Array:

To flatten a deep nested array, we could modify our code to recursively flatten the array, like so:

// ES5+
function flatten(arr) {
  return Array.isArray(arr) ? [].concat.apply([], arr.map(flatten)) : arr;
}

console.log(flatten(users));

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    { id: 7, name: 'Melissa' },
    { id: 2, name: 'David' },
] */

Using Array.reduce() and Array.concat()

We can use reduce() with concat() to flatten an array one-level deep like so:

// ES5+
const flattened = users.reduce(function (accumulator, user) {
    return accumulator.concat(user);
}, []);

// ES6+
const flattened = users.reduce((accumulator, user) => accumulator.concat(user), []);

console.log(flattened);

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    [ { id: 7, name: 'Melissa' }, { id: 2, name: 'David' } ],
] */

This works because in Array.reduce() the first argument is an accumulator, whose value is remembered across each iteration, and ultimately becomes the final, single resulting value.

This might not be most efficient solution when working with large arrays because in each iteration, it creates a new temporary array that must be garbage-collected, and it copies elements from the current accumulator array into a new array instead of adding the new elements to the existing array.

Flatten Deep Nested Array:

To flatten a deep nested array, we could modify our code to recursively flatten the array, like so:

// ES5+
const flatten = function (arr) {
    return arr.reduce(function (accumulator, value) {
        const flattened = Array.isArray(value) ? flatten(value) : value;

        return accumulator.concat(flattened);
    }, []);
};

console.log(flatten(users));

/* output: [
    { id: 1, name: 'John' },
    { id: 3, name: 'Wayne' },
    { id: 7, name: 'Melissa' },
    { id: 2, name: 'David' },
] */

Due to potential performance issues associated with using reduce() and concat() together for large arrays, it might be a good idea to use alternatives instead.


Hope you found this post useful. It was published . Please show your love and support by sharing this post.