62

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]?

zangw
  • 43,869
  • 19
  • 177
  • 214
  • 2
    See this discussion here: http://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript – Anderson Green Dec 03 '14 at 08:08
  • 5
    [[[0], [1]], [[2], [3]], [[4], [5]]].toString().split(",").map(Number); – dandavis Dec 03 '14 at 08:11
  • 2
    @dandavis this is black magic. What if he has strings or other types? :D – Leo Dec 03 '14 at 08:58
  • @LeoDeng: i didn't see any strings, and other methods would be too complicated to fit in a comment... – dandavis Dec 03 '14 at 09:00
  • @dandavis I mean, he was just taking 12345 for an example, I assume. Essentially I think it should be a recursion. The code he posted was from this page: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Example:_Flatten_an_array_of_arrays – Leo Dec 03 '14 at 09:02
  • The same code you've posted is working on nested array of any depth. – Deekshith Feb 19 '16 at 00:59
  • @deekshith, `[[[0], [1]], [[2], [3]], [[4], [5]]].reduce(function(a, b) { return a.concat(b); });` just return `[[0], [1], [2], [3], [4], [5]]`, rather than `[0, 1, 2, 3, 4, 5]` – zangw Feb 19 '16 at 01:22
  • @zangw Thats strange. I've tried it just now on Firefox 46 Dev edition and Chrome 48 and it returns `[0, 1, 2, 3, 4, 5]` for me. Try this: http://www.es6fiddle.com/ikt0pffy/ – Deekshith Feb 19 '16 at 01:31
  • @deekshith, I test it under Chrome console. it give the result as I mentioned before. I am not sure why es6fiddle give that result...it is weird... maybe bug – zangw Feb 19 '16 at 01:40
  • This SO question is the answer for this bonfire on Free Code Camp: https://www.freecodecamp.com/challenges/steamroller – mobesa Sep 12 '16 at 17:54
  • This question is definitely not a duplicate, as this one addresses more than one level of depth – axelduch May 15 '17 at 07:40
  • `const arr = [1, 2, '22',[1,33,44,['ddd'], 5678], 'abbb', 'ccc', 1234];` `const flat = String(arr).split(',').map((elm)=> {` `return !isNaN(elm) ? Number(elm) : elm` `})` `console.log(flat)` – D V Yogesh Mar 21 '23 at 16:24

27 Answers27

70

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]
Leo
  • 13,428
  • 5
  • 43
  • 61
52

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.

Inkling
  • 3,544
  • 4
  • 30
  • 44
  • Good practice for ES6 – zangw Feb 24 '16 at 02:55
  • 1
    any draw back to calling this method with infinity as the other answer suggests? we don't always know the depth of the array. – Angela P Aug 16 '21 at 17:31
  • @AngelaP It's designed to be used like that, however in practice it seems there's a limit to how deep the array can go. After testing, for me in Chrome that limit seems to be 7387 - any more and it will throw a "Maximum call stack size exceeded" error. I'm also able to flatten an array with a circular reference (i.e. infinitely recursive) up to that limit - in other words `.flat(7387)` works but `.flat(7388)` throws the same error. Other browsers/engines may behave differently, but if the arrays you're operating on are anywhere near that deep I think you have bigger issues. – Inkling Feb 14 '22 at 08:37
43

This is an alternative to recursion (see jsfiddle here) and should accept any level of depth which avoids stack overflow.

var array = [[0, 1], [2, 3], [4, 5, [6, 7, [8, [9, 10]]]]];
console.log(flatten(array), array); // does not mutate array
console.log(flatten(array, true), array); // array is now empty

// This is done in a linear time O(n) without recursion
// memory complexity is O(1) or O(n) if mutable param is set to false
function flatten(array, mutable) {
    var toString = Object.prototype.toString;
    var arrayTypeStr = '[object Array]';
    
    var result = [];
    var nodes = (mutable && array) || array.slice();
    var node;

    if (!array.length) {
        return result;
    }

    node = nodes.pop();
    
    do {
        if (toString.call(node) === arrayTypeStr) {
            nodes.push.apply(nodes, node);
        } else {
            result.push(node);
        }
    } while (nodes.length && (node = nodes.pop()) !== undefined);

    result.reverse(); // we reverse result to restore the original order
    return result;
}
axelduch
  • 10,769
  • 2
  • 31
  • 50
  • 2
    Why are you using `Object.prototype.toString.call(node) == '[object Array]'` instead of `Array.isArray(node)`? – Hart Simha Dec 04 '14 at 03:57
  • 2
    It's just for ie8 and below – axelduch Dec 04 '14 at 08:17
  • 9
    sneaky using apply in there to split the arr, love it. – Alex Boisselle Jul 08 '16 at 15:49
  • Why not use instanceof operator instead of toString? if (node instanceof Array) { nodes.push.apply(nodes, node); } else { result.push(node); } – Danny Jul 31 '16 at 19:03
  • You could do that too, yes. Matter of taste at this point – axelduch Aug 03 '16 at 06:37
  • @axelduch may i (or someone else) turn this into a module (npm etc.)? – Moritz Mahringer Feb 06 '17 at 02:16
  • You are free to use the code as you wish, and even though it is probably debatable to turn this into a module on its own, since it is more a helper than a complete module I would not try to go against it. Cheers :) – axelduch Feb 06 '17 at 13:21
  • If it avoids Stack Overflow, why is it here? –  Mar 31 '18 at 21:16
  • This is great, however it seems like if `mutable` is true, just simple the single line `var nodes = (mutable && array) || array.slice();` seems to perform a _deep_ copy of the array passed to the function. How/why is this possible!? – Afs35mm Apr 11 '18 at 02:29
  • Would `nodes = [...nodes, ...node]` also leave the elements in place, so would keep memory consumption O(1) without using the slightly obscure `apply` syntax? (Appreciate this answer was written long before we got `...` - just curious whether I understand this properly.) – Chris Oct 22 '21 at 10:01
39

ES2019 solution:

ary.flat(Infinity);

That's it. It's that simple. You can change Infinity to be the appropriate level of flattenedness if you wish.

Example:

console.log([[[0], [1]], [[2], [3]], [[4], [5]]].flat(Infinity));

Other, longer solutions that work with older browsers below.


Based on @Leo's solution, but faster by reusing the same array and preventing .concat

function flatten(ary, ret = []) {
    for (const entry of ary) {
        if (Array.isArray(entry) {
            flatten(entry, ret);
        } else {
            ret.push(entry);
        }
    }
    return ret;
}
console.log(flatten([[[0], [1]], [[2], [3]], [[4], [5]]]));

Or with Array.prototype.reduce, since you mentioned it:

function flatten(ary, ret = []) {
    return ary.reduce((ret, entry) => {
        if (Array.isArray(entry)) {
            flatten(entry, ret);
        } else {
            ret.push(entry);
        }
        return ret;
    }, ret);
}
console.log(flatten([[[0], [1]], [[2], [3]], [[4], [5]]]));
Timothy Gu
  • 3,727
  • 28
  • 35
  • 1
    Probably the best and most readable solution out here – mobesa Sep 13 '16 at 13:08
  • Much, much, much better answer than most here. There's no good reason at all for all of the temporary arrays floating around the other answers. – T.J. Crowder Feb 27 '17 at 13:16
  • @timothygu can you explain how will you describe time and space complexity of both solutions in Big-O Notation? – Uthman Mar 12 '17 at 09:52
  • 1
    @baltusaj Asymptotic analysis is pretty much useless for this specific case, since all solutions in this question follow essentially the same algorithm. It's about the constant terms (like creation of an empty array) that differentiate this solution from the rest. – Timothy Gu Mar 20 '17 at 04:44
  • This is still slower than the accepted answer. – mjwrazor Nov 30 '17 at 18:24
16

ES6 one-liner:

function flatten(a) {
    return Array.isArray(a) ? [].concat(...a.map(flatten)) : a;
}

Also, non-recursive version for very deep arrays (not very efficient but rather elegant)

function flatten(a) {
    var queue = a.slice();
    var result = [];
    while(queue.length) {
        let curr = queue.pop();
        if(Array.isArray(curr)) {
            queue.push(...curr);
        }
        else result.push(curr);
    }
    return result;
}
matanso
  • 1,284
  • 1
  • 10
  • 17
  • You ES6 one-liner looks very nice but can you add explanation about how is it working exactly? – Uthman Mar 12 '17 at 09:45
  • 1
    @baltusaj it's a recursive solution. If the current element is not an array, return it. If it is, flatten every element of the array (using Array.map) and then concatenate the resulting arrays (using Array.concat and spreading the array to function parameters) – matanso Mar 12 '17 at 09:49
  • thanks. I guess the "spreading" is done by the three dots. – Uthman Mar 12 '17 at 09:54
  • more es6 magic: let flatten = a => Array.isArray(a) ? [].concat(...a.map(flatten)) : a; – nathan hayfield Jul 07 '17 at 17:03
  • the second implementation failed [my tests](https://codepen.io/mindplay-dk/pen/EbeVGP) – mindplay.dk Nov 27 '17 at 14:47
  • 1
    @matanso your non recursive solution is printing the array in reverse order, instead on queue.pop() if you use queue.shift() it will work fine as expected. – krishna teja Sep 10 '20 at 05:02
8

Flattens 2 levels only:

var arr = [1, [2, 3], [4, 5, 6]];
[].concat.apply([], arr) // -> [1, 2, 3, 4, 5, 6]
artnikpro
  • 5,487
  • 4
  • 38
  • 40
5

This is already answered but I am just studying JS and wonder what about:

    var array = [[[0], [1]], [[2], [3]], [[4], [5]]];
    var flattend = array.join(",").split(",");
    console.log(flattend);

Only side affect is that the join converts all items to strings, but that can be easilly fixed

Johan Meester
  • 67
  • 1
  • 2
  • 6
    For numbers and strings this solution is pretty intelligent, but the problem becomes more complicated when objects and functions are involved. – Timothy Gu Jan 13 '16 at 03:19
  • I was looking for easy solution to use on strings arrays. This one is perfect. – Ofir Kariv Apr 22 '21 at 13:27
5

I like my solution :)

var flattenClosure = function(a) {
    var store = [];

    return function() {
        var internMapper = function(b) {
            if (Array.isArray(b)) {
                return b.map(internMapper);
            }
            store.push(b);
            return b;
        }
        a.map(internMapper);
        return store;
    }
};

console.log(flattenClosure([[[[[[[[1]]]], [2], [4], [6, 8, 9], 2]]], 10, 11, [15, 17, 20], [], 33])());
dashambles
  • 529
  • 8
  • 22
4

If you're aware the array is made up of only numbers you can just do the following:

array.join().split(',').map(Number);
MikeOlo
  • 49
  • 2
4

Inspired by code from Eloquent JavaScript and the answer provided by @axelduch (A lot more efficient from what I can tell too.)

function flatten(array, mutable) {
  var nodes = (mutable && array) || array.slice(); // return a new array.
  var flattened = [];

  for (var node = nodes.shift(); node !== undefined; node = nodes.shift()) {
    if (Array.isArray(node)) {
      nodes.unshift.apply(nodes, node);
    } else {
      flattened.push(node);
    }
  }

  return flattened;
}
4

Disclaimer: I know that it is an old and already answered question, but @Nick has got me into it as I have commented his answer as one of the most expensive way to flatten an array. I haven't been coding JavaScript for years, but it's like riding a bike - once you learn you'll never forget ;)

Here is my full recursive code (no for loop needed):

var flattened = [];
function flatten(a, i) {
    if(a.length > i) {
        if(Array.isArray(a[i]))
            flatten(a[i], 0);
        else
            flattened.push(a[i]);
        flatten(a, i + 1);
    }
}

flatten([[0, 1], [2, 3], [4, 5]], 0);
console.log(flattened);

I have tested it against toString().split(',') solution and mine is about 7 times faster. That's what I mean when talking about expensiveness ;)

Adam
  • 5,403
  • 6
  • 31
  • 38
3
function flatten(array) {
    return array.reduce(
        (previous, current) =>
            Array.isArray(current)
            ? [...previous, ...flatten(current)]
            : [...previous, current]
        , []
    );
}
Joe Chung
  • 11,955
  • 1
  • 24
  • 33
  • 3
    While this code may answer the question, providing additional context regarding *why* and/or *how* this code answers the question improves its long-term value. – Benjamin W. Mar 11 '16 at 06:48
2
var nested = [[[0], [1]], [[2], [3]], [[4], [5]]];
var flattened = [].concat.apply([],[].concat.apply([],nested));
console.log('-> flattened now: ' + flattened);
falsecrypt
  • 1,536
  • 14
  • 11
  • if we change `nested` to `[[[0], [[1]]], [[2], [3]], [[4], [5]]]` it would flatten everything... also when printing, cannot use `+` or else some debugger might print out by flattening things for you, need to use a `,` instead – nonopolarity Nov 20 '15 at 22:30
  • This solution limits the depth to at most three levels. For example, `[[[[4]]]]` will return `[[4]]` rather than `[4]`. – Timothy Gu Jan 13 '16 at 02:56
2

Based on dashamble's answer, but I believe this is a bit simpler to understand:

var steamroller = function(arr) {
  var result = [];

  var dropHeavyObject = function(auxArr) {
    var flatnd = [];

    flatnd = auxArr.map(function(x) {
      if(Array.isArray(x)) {
        return dropHeavyObject(x);
      } else {
        result.push(x);
        return x;
      }
    });

    return flatnd;
  };

  dropHeavyObject(arr);
  return result;
}
Community
  • 1
  • 1
Tudor Leustean
  • 517
  • 3
  • 15
2

There are three utility functions in lodash related to your question flatten, flattenDeep, flattenDepth in lodash. flatten goes into a single depth, flattenDeep goes all the way into the deepest level and flattenDepth gives you the choice of "how deep" to flatten.

Example:

> var arr = [[[0], [1]], [[2], [3]], [[4], [5]]];
> _.flattenDeep(arr)
   [0, 1, 2, 3, 4, 5]
Thoran
  • 8,884
  • 7
  • 41
  • 50
zangw
  • 43,869
  • 19
  • 177
  • 214
2
var flattenWithStack = function(arr) {
  var stack = [];
  var flat = [];
  stack.push(arr);
  while(stack.length > 0) {
    var curr = stack.pop();
    if(curr instanceof Array) {
      stack = stack.concat(curr);
    } else {
      flat.push(curr);
    }
  }
  return flat.reverse();
}

Non recursive. Basically dfs.

lilcpu
  • 21
  • 2
1
function flatten(x) {
  if (x.length == 0) {return []};
  if (Array.isArray(x[0])) {
    return flatten(x[0].concat(flatten(x.slice(1,x.length))));
  }
  return [].concat([x[0]], flatten(x.slice(1,x.length)));
}

recursively flattens the array.

Hart Simha
  • 862
  • 8
  • 14
  • 1
    Cannot handle deeper structure though, `flatten([[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]])` returns `[1, 4, 5, 0, 2, 3]`. – Leo Dec 03 '14 at 09:56
  • Thank you for pointing this out. I edited my answer to provide a solution that preserves element order (which is similar to your excellent solution). – Hart Simha Dec 03 '14 at 20:42
1

I was having this issue the other day and discovered a little hack... actually I just realized it's very similar to the last answer and like comment to the above answer indicates, it won't work for objects, but for simple numbers etc. it works just fine.

If you take a nested array to string, it separates the values by commas. Then you can split it by commas to form a string. If you then need to convert the strings to int or float, you can run through the new array converting each value.

stringArray = [[0, 1], [2, 3], [4, 5]].toString().split(',');
stringArray.forEach((v,i,a) => a[i] = parseFloat(a[i]));
Nick
  • 91
  • 2
  • 8
  • I think that's one of the most expensive way to flatten an array. – Adam Jun 20 '16 at 16:09
  • Thanks, Adam. I'm a newbie, and was experimenting with the functions when I discovered this cheat ;) How do you estimate expense? – Nick Jun 21 '16 at 20:47
  • Heh, you've got me into this question ;) Please, take a look at my answer. – Adam Jun 21 '16 at 21:56
  • Thanks! Good news is I learned how to do it recursively shortly after I posted the newbie hack above, and it's (using recursion) so easy it's really not worth doing it another way. I see what you mean by expense! – Nick Jun 23 '16 at 12:26
1

An implementation with functional programming

With functional programming we can simply derive flatten from another more generic function: traverse.

The latter is a function to traverse and reduce arbitrarily nested arrays just like flat arrays. This is possible because nested arrays with unknown depth are no more than a particular version of a tree data structure:

const traverse = f => g => acc => xs => {
  let [leaf, stack] = xs[0][0] === undefined
   ? [xs[0], xs.slice(1)]
   : f([]) (xs);

  return stack.length
   ? traverse(f) (g) (g(leaf) (acc)) (stack)
   : g(leaf) (acc);
};

const dfs = stack => tree => tree[0] === undefined 
 ? [tree, stack]
 : dfs(tree.length > 1 ? concat(stack) (tree.slice(1)) : stack) (tree[0]);

const concat = ys => xs => xs.concat(ys);
const flatten = f => traverse(f) (concat) ([]);

const xs = [[[1,2,3],4,5,6],7,8,[9,10,[11,12],[[13]],14],15];

console.log(flatten(dfs) (xs));

Please note that tree data structures can either be traversed by depth first (DFS) or by breadth first (BFS). Arrays are usually traversed in depth first order.

As I said traverse is a generic reduction function like reduce for flat arrays. So we can easily calculate the sum of all elements as well:

const add = y => x => x + y;
traverse(dfs) (add) (0) (xs); // 120

Conclusion: To flatten an arbitrarily nested array in a functional way we just need a one-liner: const flatten = f => traverse(f) (concat) ([]);. All other involved functions are generic and have a whole range of other potential applications. This is 100% reusability!

Community
  • 1
  • 1
1

Using JSON.stringify and JSON.parse

arr = JSON.parse("[" + 
               JSON.stringify(arr)
                   .replace(/[\[\]]+/g,"")
                   .replace(/,,/g,",") +
               "]");
August
  • 1,722
  • 5
  • 20
  • 37
1

Using Lisp conventions.

Using .shift() and .concat() is inefficient, however.

    flatten (array) {

        // get first element (car) and shift array (cdr) 
        var car = array.shift();

        // check to see if array was empty
        if (car === undefined) {
            return [];

        // if the first element (car) was an array, recurse on it
        } else if (_.isArray(car)) {
            return flatten(car).concat(flatten(array));

        // otherwise, cons (concatenate) the car to the flattened version of cdr (rest of array)
        } else {
            return [car].concat(flatten(array))
        }
    }
Ishaan Taylor
  • 1,817
  • 5
  • 17
  • 19
1
// implementation
function flattenArray(){
  const input = arguments[0]
      , output = flatten(input)

  function flatten(){
    return [].concat.apply([], arguments[0])
  }

  return input.length === output.length
    ? output
    : flattenArray(output)
}

// how to use?
flattenArray([1,2,[3]) // return [1,2,3]

Test Cases -> https://github.com/CHAOWEICHIU/ccw-custom-functions/blob/master/test/units/flattenArray.js

Wayne Chiu
  • 5,830
  • 2
  • 22
  • 19
1
function flatten(arrayOfArrays) {
  return arrayOfArrays.reduce(function(flat, subElem) {
    return flat.concat(Array.isArray(subElem) ? flatten(subElem) : subElem);
  }, []);
}


var arr0 = [0, 1, 2, 3, 4];
var arr1 = [[0,1], 2, [3, 4]];
var arr2 = [[[0, 1], 2], 3, 4];
console.log(flatten(arr0));  // [0, 1, 2, 3, 4]
console.log(flatten(arr1));  // [0, 1, 2, 3, 4]
console.log(flatten(arr2));  // [0, 1, 2, 3, 4]
console.log(flatten([]));    // []
JRJ
  • 11
  • 3
0

If you have an infinitely nested array like a below, here's what I'd do.

const a = [[1,2,[3]],4]

Array.prototype.flatten = (array) => {
  const newArray = []
  const flattenHelper = (array) => {
    array.map(i => {
      Array.isArray(i) ? flattenHelper(i) : newArray.push(i)
    })
  }
  flattenHelper(a)
  return newArray
}

const newArray = a.flatten()
console.log(newArray);
urubuz
  • 352
  • 1
  • 13
0

Heres what I've got:

function steamrollArray(arr) {
  // the flattened array
  var newArr = [];

  // recursive function
  function flatten(arr, newArr) {
    // go through array
    for (var i = 0; i < arr.length; i++) {
      // if element i of the current array is a non-array value push it
      if (Array.isArray(arr[i]) === false) {
        newArr.push(arr[i]);
      }
      // else the element is an array, so unwrap it
      else {
        flatten(arr[i], newArr);
      }
    }
  }

  flatten(arr, newArr);

  return newArr;
}
Yup.
  • 1,883
  • 21
  • 18
0

Can be solved like this

const array = [[0, 1], [2, 3], [4, 5, [6, 7, [8, [9, 10]]]]];

const flatten(arr) => arr.reduce((acc, item) => 
   acc.concat(Array.isArray(item) ? flatten(item) : item);
}, []);

console.log(flatten(array));

Be aware that in case of the deep arrays, the TCO should be applied

The version with the TCO with the recursion solution

const array = [[0, 1], [2, 3], [4, 5, [6, 7, [8, [9, 10]]]]];

const flatten = (() => {
  const _flatten = (acc, arr) => arr.reduce((acc, item) =>  acc.concat(Array.isArray(item) ? _flatten([], item) : item), acc);

  return arr => _flatten([], arr);
})();

console.log(flatten(array))
frontendgirl
  • 787
  • 5
  • 14
0

Think this function works.

 function flatten(arr){
     return arr.reduce(function(a,b){
        return [].concat(Array.isArray(a)? flatten(a) :a,Array.isArray(b)? flatten(b):b);
      });

}
Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
Philipl
  • 395
  • 4
  • 21