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]
Answer from Leo on Stack OverflowPerfect 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]
ES6-style with recursion:
Redacted
June 2018 Update:
There is now an ES proposal for an Array.prototype.flat method. It is currently at stage 3, meaning it's likely to be implemented by browsers soon(ish) and make it into the spec in its current form. There are probably some polyfills floating around.
Example:
const nested = [[[0], [1]], [[2], [3]], [[4], [5]]];
const flattened = nested.flat(2); // Need to specify depth if > 1
June 2019 Update:
Array.prototype.flat was officially added to the language in the ES2019 spec.
Flatten a nested array without using the inbuilt flat() method (interview learning)
How to flatten this nested array
Flattened an array without using array.flat
Introducing a Method to Flatten Nested Arrays in Repository!
Videos
In an interview, I was asked to flatten a nested array in JavaScript without using `flat()`.
Under pressure, I got stuck. Later, I realized it wasn’t that hard — I was just overthinking.
Here’s the recursive solution I wrote:
var array = [0, [1, 2, [33, 44]], [4, 5, 6, 7], [7, 8], 90];
var newArr = [];
function getFlatArray(array) {
for (let index = 0; index < array.length; index++) {
if (typeof array[index] === "number") {
newArr.push(array[index]);
} else {
getFlatArray(array[index]);
}
}
}
getFlatArray(array);
console.log(newArr);
(12) [0, 1*,* 2*,* 33*,* 44*,* 4*,* 5*,* 6*,* 7*,* 7*,* 8*,* 90*]*
Given this
[
[{name: 'larry'}, {name: 'harry'}, {name: 'barry'}],
[{age: 29}, {age: 26}, {age: 34}],
[{job: 'spy'}, {job: 'seal'}, {job: 'hitman'}]
]How do I get this?
[
[{name: 'larry', age: 29, job: 'spy'}],
[{name: 'harry', age: 26, job: 'seal'}],
[{name: 'barry', age: 34, job: 'hitman'}]
]I'm a bit stuck with this so some help would be great. I've tried combinations of reduce, flat, and map array functions but not getting the desired result.
Working with restructuring collections / data wrangling isn't my strong suit. Can anyone recommend some resources to help with this?
Thanks.