Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flatten nested array in javascript? [duplicate]

As we know, to flatten the array [[0, 1], [2, 3], [4, 5]] by using the method reduce()

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {   return a.concat(b); }); 

So how to flatten this array [[[0], [1]], [[2], [3]], [[4], [5]]] to [0, 1, 2, 3, 4, 5]?

like image 550
zangw Avatar asked Dec 03 '14 08:12

zangw


People also ask

How do you flatten a nested array?

To flatten any depth of a nested array, use the Infinity with the flat() method.

Which method is used to convert nested arrays to objects?

toString() method is used to convert: an array of numbers, strings, mixed arrays, arrays of objects, and nested arrays into strings.


1 Answers

Perfect use case for recursion, which could handle even deeper structure:

function flatten(ary) {     var ret = [];     for(var i = 0; i < ary.length; i++) {         if(Array.isArray(ary[i])) {             ret = ret.concat(flatten(ary[i]));         } else {             ret.push(ary[i]);         }     }     return ret; }  flatten([[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]]) // [0, 1, 2, 3, 4, 5] 

Alternatively, as an Array method:

Array.prototype.flatten = function() {     var ret = [];     for(var i = 0; i < this.length; i++) {         if(Array.isArray(this[i])) {             ret = ret.concat(this[i].flatten());         } else {             ret.push(this[i]);         }     }     return ret; };  [[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flatten() // [0, 1, 2, 3, 4, 5] 

EDIT #1: Well, think it a little bit functional way (except for the named recursion which should be using Y-combinator for pure functional :D).

function flatten(ary) {   return ary.reduce(function(a, b) {     if (Array.isArray(b)) {       return a.concat(flatten(b))     }     return a.concat(b)   }, []) } 

Let's adopt some ES6 syntax which makes it even shorter, in one line.

const flatten = (ary) => ary.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []) 

But remember, this one cannot be applied as an array method, because arrow functions don't have theirs own this.


EDIT #2: With the latest Array.prototype.flat proposal this is super easy. The array method accepts an optional parameter depth, which specifies how deep a nested array structure should be flattened (default to 1).

[[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flat()  // [[[[0]], [1]], [[[2], [3]]], [[4], [5]]] [[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flat(2) // [[[0]], [1], [[2], [3]], [4], [5]] [[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flat(3) // [[0], 1, [2], [3], 4, 5] [[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flat(4) // [0, 1, 2, 3, 4, 5] 

So to flatten an array of arbitrary depth, just call flat method with Infinity.

[[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flat(Infinity) // [0, 1, 2, 3, 4, 5] 
like image 81
Leo Avatar answered Oct 02 '22 08:10

Leo