[javascript] Merge/flatten an array of arrays

I have a JavaScript array like:

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

How would I go about merging the separate inner arrays into one like:

["$6", "$12", "$25", ...]

This question is related to javascript arrays flatten

The answer is


If you only have arrays with 1 string element:

[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');

will do the job. Bt that specifically matches your code example.


That's not hard, just iterate over the arrays and merge them:

var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];

for (var i = 0; i < input.length; ++i) {
    result = result.concat(input[i]);
}

Here's another deep flatten for modern browsers:

function flatten(xs) {
  xs = Array.prototype.concat.apply([], xs);
  return xs.some(Array.isArray) ? flatten(xs) : xs;
};

Here is a version in Typescript based on the answer by artif3x, with a bonus implementation of flatMap for Scala fans.

function flatten<T>(items: T[][]): T[] {
  return items.reduce((prev, next) => prev.concat(next), []);
}

function flatMap<T, U>(items: T[], f: (t: T) => U[]): U[] {
  return items.reduce((prev, next) => prev.concat(f(next)), new Array<U>());
}

There is 2 way to flat your array

*1-First One You Can Use Array.prototype.flat Method

const veryDeep = [[1, [2, 2, [3, [4, [5, [6]]]]], 1]];

veryDeep.flat(Infinity)
 // [1, 2, 2, 3, 4, 5, 6, 1]
 /**  If you don't know the depth of the array, 
simply pass Infinity **\

Or You Can Put Argument If You Know How Much Nested Your Array Is

const twoLevelsDeep = [[1, [2, 2], 1]];
//depth = 1
twoLevelsDeep.flat();
[1, [2, 2], 1]

//depth = 2
twoLevelsDeep.flat(2);
// [1, 2, 2, 1]

enter image description here

*2-Second Way You Can Flat Your Array By Using Spread Operator In ES6 And Concat It Will Flat Your Array Regardless How Many Nested In It

 const multidimension = [, [, , ], , [, ]];

   [].concat(...multidimension); // This will return: [, , , , , , 
   ]

   const multidimension = [1, [2, 3, 4], 5, [6, 7]];

   [].concat(...multidimension); // This will return: [1, 2, 3, 4, 5, 6, 7]

I originally thought to use the .reduce method and recursively call a function to flatten inner arrays, however this can lead to stack overflows when you are working with a deeply nested array of deeply nested arrays. Using concat is also not the best way to go, because each iteration will create a new shallow copy of the array. What we can do instead is this:

const flatten = arr => {
    for(let i = 0; i < arr.length;) {
        const val = arr[i];
        if(Array.isArray(val)) {
            arr.splice(i, 1, ...val);
        } else {
            i ++;
        }
    }
    return arr;
}

We are not creating new arrays via concat and we are not recursively calling any functions.

http://jsbin.com/firiru/4/edit?js,console


You can flatten an array of arrays using Array.prototype.reduce() and Array.prototype.concat()

_x000D_
_x000D_
var data = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]].reduce(function(a, b) {_x000D_
  return a.concat(b);_x000D_
}, []);_x000D_
console.log(data);
_x000D_
_x000D_
_x000D_

Related docs: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce


Much simpler and straight-forward one; with option to deep flatten;

const flatReduce = (arr, deep) => {
    return arr.reduce((acc, cur) => {
        return acc.concat(Array.isArray(cur) && deep ? flatReduce(cur, deep) : cur);
    }, []);
};

console.log(flatReduce([1, 2, [3], [4, [5]]], false)); // =>  1,2,3,4,[5]
console.log(flatReduce([1, 2, [3], [4, [5, [6, 7, 8]]]], true)); // => 1,2,3,4,5,6,7,8

It's better to do it in a recursive way, so if still another array inside the other array, can be filtered easily...

const flattenArray = arr =>
  arr.reduce(
    (res, cur) =>
       !Array.isArray(cur) 
       ? res.concat(cur)
       : res.concat(flattenArray(cur)), []);

And you can call it like:

flattenArray([[["Alireza"], "Dezfoolian"], ["is a"], ["developer"], [[1, [2, 3], ["!"]]]);

and the result isas below:

["Alireza", "Dezfoolian", "is a", "developer", 1, 2, 3, "!"]

There's a new native method called flat to do this exactly.

(As of late 2019, flat is now published in the ECMA 2019 standard, and core-js@3 (babel's library) includes it in their polyfill library)

const arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

// Flatten 2 levels deep
const arr3 = [2, 2, 5, [5, [5, [6]], 7]];
arr3.flat(2);
// [2, 2, 5, 5, 5, [6], 7];

// Flatten all levels
const arr4 = [2, 2, 5, [5, [5, [6]], 7]];
arr4.flat(Infinity);
// [2, 2, 5, 5, 5, 6, 7];

There's a much faster way of doing this than using the merge.concat.apply() method listed in the top answer, and by faster I mean more than several orders of magnitude faster. This assumes your environment has access to the ES5 Array methods.

var array2d = [
  ["foo", "bar"],
  ["baz", "biz"]
];
merged = array2d.reduce(function(prev, next) {
    return prev.concat(next);
});

Here's the jsperf link: http://jsperf.com/2-dimensional-array-merge


Simple flatten util i've written

const flatten = (arr, result = []) => {
    if (!Array.isArray(arr)){
        return [...result, arr];
    }
     arr.forEach((a) => {
         result = flatten(a, result)
    })

    return result
}

console.log(flatten([1,[2,3], [4,[5,6,[7,8]]]])) // [ 1, 2, 3, 4, 5, 6, 7, 8 ]

[1,[2,3],[4,[5,6]]].reduce(function(p, c) {
    return p.concat(c instanceof Array ? 
                    c.reduce(arguments.callee, []) : 
                    [c]); 
}, []);

In Node environment, if your version is not support Array.prototype.flat but you use es6 or ts, then you can do like this

_x000D_
_x000D_
const arrays = [
  ["$6"],
  ["$12"],
  ["$25"],
  ["$25"],
  ["$18"],
  ["$22"],
  ["$10"]
];
const merged = [].concat(...arrays);

console.log(merged);
_x000D_
_x000D_
_x000D_


const common = arr.reduce((a, b) => [...a, ...b], [])

The logic here is to convert input array to string and remove all brackets([]) and parse output to array. I'm using ES6 template feature for this.

var x=[1, 2, [3, 4, [5, 6,[7], 9],12, [12, 14]]];

var y=JSON.parse(`[${JSON.stringify(x).replace(/\[|]/g,'')}]`);

console.log(y)

just the best solution without lodash

let flatten = arr => [].concat.apply([], arr.map(item => Array.isArray(item) ? flatten(item) : item))

I have a simple solution without using in a special js function. (like reduce etc)

const input = [[0, 1], [2, 3], [4, 5]]
let flattened=[];

for (let i=0; i<input.length; ++i) {
    let current = input[i];
    for (let j=0; j<current.length; ++j)
        flattened.push(current[j]);
}

A solution for the more general case, when you may have some non-array elements in your array.

function flattenArrayOfArrays(a, r){
    if(!r){ r = []}
    for(var i=0; i<a.length; i++){
        if(a[i].constructor == Array){
            r.concat(flattenArrayOfArrays(a[i], r));
        }else{
            r.push(a[i]);
        }
    }
    return r;
}

You can use Underscore:

var x = [[1], [2], [3, 4]];

_.flatten(x); // => [1, 2, 3, 4]

Using the spread operator:

_x000D_
_x000D_
const input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];_x000D_
const output = [].concat(...input);_x000D_
console.log(output); // --> ["$6", "$12", "$25", "$25", "$18", "$22", "$10"]
_x000D_
_x000D_
_x000D_


try this method,

_x000D_
_x000D_
arr = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]_x000D_
concat_arr = arr.concat.apply([], arr)_x000D_
console.log(concat_arr)
_x000D_
_x000D_
_x000D_


Another ECMAScript 6 solution in functional style:

Declare a function:

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

and use it:

flatten( [1, [2,3], [4,[5,[6]]]] ) // -> [1,2,3,4,5,6]

_x000D_
_x000D_
 const flatten = arr => arr.reduce(_x000D_
         (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []_x000D_
       );_x000D_
_x000D_
_x000D_
console.log( flatten([1, [2,3], [4,[5],[6,[7,8,9],10],11],[12],13]) )
_x000D_
_x000D_
_x000D_

Consider also a native function Array.prototype.flat() (proposal for ES6) available in last releases of modern browsers. Thanks to @(?????????? ???) and @(Mark Amery) mentioned it in the comments.

The flat function has one parameter, specifying the expected depth of array nesting, which equals 1 by default.

[1, 2, [3, 4]].flat();                  // -> [1, 2, 3, 4]

[1, 2, [3, 4, [5, 6]]].flat();          // -> [1, 2, 3, 4, [5, 6]]

[1, 2, [3, 4, [5, 6]]].flat(2);         // -> [1, 2, 3, 4, 5, 6]

[1, 2, [3, 4, [5, 6]]].flat(Infinity);  // -> [1, 2, 3, 4, 5, 6]

_x000D_
_x000D_
let arr = [1, 2, [3, 4]];_x000D_
_x000D_
console.log( arr.flat() );_x000D_
_x000D_
arr =  [1, 2, [3, 4, [5, 6]]];_x000D_
_x000D_
console.log( arr.flat() );_x000D_
console.log( arr.flat(1) );_x000D_
console.log( arr.flat(2) );_x000D_
console.log( arr.flat(Infinity) );
_x000D_
_x000D_
_x000D_


Here's a short function that uses some of the newer JavaScript array methods to flatten an n-dimensional array.

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

Usage:

flatten([[1, 2, 3], [4, 5]]); // [1, 2, 3, 4, 5]
flatten([[[1, [1.1]], 2, 3], [4, 5]]); // [1, 1.1, 2, 3, 4, 5]

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

Per request, Breaking down the one line is basically having this.

function flatten(array) {
  // reduce traverses the array and we return the result
  return array.reduce(function(acc, b) {
     // if is an array we use recursion to perform the same operations over the array we found 
     // else we just concat the element to the accumulator
     return acc.concat( Array.isArray(b) ? flatten(b) : b);
  }, []); // we initialize the accumulator on an empty array to collect all the elements
}

solve this problem using single line of code..

_x000D_
_x000D_
function unflatten(arr){_x000D_
    return arr.reduce((prevProps, nextProps) => {_x000D_
        return prevProps.concat(Array.isArray(nextProps) ? unflatten(nextProps) : nextProps)_x000D_
    }, [])_x000D_
}
_x000D_
_x000D_
_x000D_

https://codepen.io/jyotishman/pen/BayVeoQ


To flatten an array of single element arrays, you don't need to import a library, a simple loop is both the simplest and most efficient solution :

for (var i = 0; i < a.length; i++) {
  a[i] = a[i][0];
}

To downvoters: please read the question, don't downvote because it doesn't suit your very different problem. This solution is both the fastest and simplest for the asked question.


You can also try the new Array.flat() method. It works in the following manner:

_x000D_
_x000D_
let arr = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]].flat()

console.log(arr);
_x000D_
_x000D_
_x000D_

The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the 1 layer of depth (i.e. arrays inside arrays)

If you want to also flatten out 3 dimensional or even higher dimensional arrays you simply call the flat method multiple times. For example (3 dimensions):

_x000D_
_x000D_
let arr = [1,2,[3,4,[5,6]]].flat().flat().flat();

console.log(arr);
_x000D_
_x000D_
_x000D_

Be careful!

Array.flat() method is relatively new. Older browsers like ie might not have implemented the method. If you want you code to work on all browsers you might have to transpile your JS to an older version. Check for MDN web docs for current browser compatibility.


I believe that the best way to do this would be something like this:

var flatten = function () {
  return [].slice.call(arguments).toString().split(',');
};

You can use Ramda JS flatten

_x000D_
_x000D_
var arr = [[1,2], [3], [4,5]];_x000D_
var flattenedArray = R.flatten(arr); _x000D_
_x000D_
console.log(flattenedArray)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
_x000D_
_x000D_
_x000D_


The following code will flatten deeply nested arrays:

/**
 * [Function to flatten deeply nested array]
 * @param  {[type]} arr          [The array to be flattened]
 * @param  {[type]} flattenedArr [The flattened array]
 * @return {[type]}              [The flattened array]
 */
function flattenDeepArray(arr, flattenedArr) {
  let length = arr.length;

  for(let i = 0; i < length; i++) {
    if(Array.isArray(arr[i])) {
      flattenDeepArray(arr[i], flattenedArr);
    } else {
      flattenedArr.push(arr[i]);
    }
  }

  return flattenedArr;
}

let arr = [1, 2, [3, 4, 5], [6, 7]];

console.log(arr, '=>', flattenDeepArray(arr, [])); // [ 1, 2, [ 3, 4, 5 ], [ 6, 7 ] ] '=>' [ 1, 2, 3, 4, 5, 6, 7 ]

arr = [1, 2, [3, 4], [5, 6, [7, 8, [9, 10]]]];

console.log(arr, '=>', flattenDeepArray(arr, [])); // [ 1, 2, [ 3, 4 ], [ 5, 6, [ 7, 8, [Object] ] ] ] '=>' [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

You can use Array.flat() with Infinity for any depth of nested array.

_x000D_
_x000D_
var arr = [ [1,2,3,4], [1,2,[1,2,3]], [1,2,3,4,5,[1,2,3,4,[1,2,3,4]]], [[1,2,3,4], [1,2,[1,2,3]], [1,2,3,4,5,[1,2,3,4,[1,2,3,4]]]] ];_x000D_
_x000D_
let flatten = arr.flat(Infinity)_x000D_
_x000D_
console.log(flatten)
_x000D_
_x000D_
_x000D_

check here for browser compatibility


What about deep flatten & Object Oriented ?

[23, [34, 454], 12, 34].flatten();
// -->   [23,34, 454, 12, 34]

[23, [34, 454,[66,55]], 12, 34].flatten();

// -->  [23, 34, 454, [66,55], 12, 34]

DEEP Flatten :

[23, [34, 454,[66,55]], 12, 34].flatten(true);

// --> [23, 34, 454, 66, 55, 12, 34]

DEMO

CDN


If all array elements are Integer,Float,... or/and String , So just , do this trick :

var myarr=[1,[7,[9.2]],[3],90];
eval('myarr=['+myarr.toString()+']');
print(myarr);
// [1, 7, 9.2, 3, 90]

DEMO


Using code from there.

I would write:

myArray.enumerable().selectMany(function(x) { return x; }).array()

ES-Next solutions

  1. Array.from / Set / Array.flat / Array.sort
// 1. remove duplicate item
// 2. flat array
let arr= [["$6", ["$18"]], ["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];

let result = Array.from(new Set(arr.flat(Infinity)));

console.log(`flat array with unique filter`, result);
// 

_x000D_
_x000D_
// 1. remove duplicate item_x000D_
// 2. sort by Asc order (munber only)_x000D_
// 3. flat array_x000D_
_x000D_
// let arr= [["$6", ["$18"]], ["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];_x000D_
_x000D_
let arr= [["6", ["18"]], ["6"], ["12"], ["25"], ["25"], ["18"], ["22"], ["10"]];_x000D_
_x000D_
let result = Array.from(new Set(arr.flat(Infinity))).map(Number).sort((a,b)=> a > b ? 1: -1);_x000D_
_x000D_
console.log(`flat array with unique filter & Asc sort`, result);_x000D_
//
_x000D_
_x000D_
_x000D_

  1. ...spread / Set / Array.flat / Array.sort
// 1. remove duplicate item
// 2. flat array
let arr= [["$6", ["$18"]], ["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];

let result = [...new Set(arr.flat(Infinity))];

console.log(`flat array with unique filter`, result);
// 

_x000D_
_x000D_
// 1. remove duplicate item_x000D_
// 2. sort by Asc order(number only)_x000D_
// 3. flat array_x000D_
_x000D_
//let arr= [["$6", ["$18"]], ["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];_x000D_
_x000D_
let arr= [["6", ["18"]], ["6"], ["12"], ["25"], ["25"], ["18"], ["22"], ["10"]];_x000D_
_x000D_
let result = [...new Set(arr.flat(Infinity))].map(Number).sort((a,b)=> a > b ? 1: -1);_x000D_
_x000D_
console.log(`flat array with unique filter & Asc sort`, result);_x000D_
// 
_x000D_
_x000D_
_x000D_

refs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax


if your array only consists out of integers or strings you can use this dirty hack:

var arr = [345,2,[34],2,[524,[5456]],[5456]];
var flat = arr.toString().split(',');

Works, in FF, IE and Chrome didn't test the other browsers yet.


I didn't find here solution for large arrays when flattening is not deep. So, my version:

function flatten(arr){
    result = []
    for (e of arr)
        result.push(...e)
    return result
}

Sheer Magic of ES6

const flat = A => A.reduce((A, a) => Array.isArray(a) ? [...A, ...flat(a)] : [...A, a], []);

ES6 way:

_x000D_
_x000D_
const flatten = arr => arr.reduce((acc, next) => acc.concat(Array.isArray(next) ? flatten(next) : next), [])_x000D_
_x000D_
const a = [1, [2, [3, [4, [5]]]]]_x000D_
console.log(flatten(a))
_x000D_
_x000D_
_x000D_

ES5 way for flatten function with ES3 fallback for N-times nested arrays:

_x000D_
_x000D_
var flatten = (function() {_x000D_
  if (!!Array.prototype.reduce && !!Array.isArray) {_x000D_
    return function(array) {_x000D_
      return array.reduce(function(prev, next) {_x000D_
        return prev.concat(Array.isArray(next) ? flatten(next) : next);_x000D_
      }, []);_x000D_
    };_x000D_
  } else {_x000D_
    return function(array) {_x000D_
      var arr = [];_x000D_
      var i = 0;_x000D_
      var len = array.length;_x000D_
      var target;_x000D_
_x000D_
      for (; i < len; i++) {_x000D_
        target = array[i];_x000D_
        arr = arr.concat(_x000D_
          (Object.prototype.toString.call(target) === '[object Array]') ? flatten(target) : target_x000D_
        );_x000D_
      }_x000D_
_x000D_
      return arr;_x000D_
    };_x000D_
  }_x000D_
}());_x000D_
_x000D_
var a = [1, [2, [3, [4, [5]]]]];_x000D_
console.log(flatten(a));
_x000D_
_x000D_
_x000D_


Array.prototype.flatten = Array.prototype.flatten || function() {
    return [].reduce.call(this, function(flat, toFlatten) {
        return flat.concat(Array.isArray(toFlatten) ? toFlatten.flatten() : toFlatten);
    },[])
};

A Haskellesque approach

_x000D_
_x000D_
function flatArray([x,...xs]){_x000D_
  return x ? [...Array.isArray(x) ? flatArray(x) : [x], ...flatArray(xs)] : [];_x000D_
}_x000D_
_x000D_
var na = [[1,2],[3,[4,5]],[6,7,[[[8],9]]],10];_x000D_
    fa = flatArray(na);_x000D_
console.log(fa);
_x000D_
_x000D_
_x000D_


Recursive version that works on all datatypes

 /*jshint esversion: 6 */

// nested array for testing
let nestedArray = ["firstlevel", 32, "alsofirst", ["secondlevel", 456,"thirdlevel", ["theinnerinner", 345, {firstName: "Donald", lastName: "Duck"}, "lastinner"]]];

// wrapper function to protect inner variable tempArray from global scope;
function flattenArray(arr) {

  let tempArray = [];

  function flatten(arr) {
    arr.forEach(function(element) {
      Array.isArray(element) ? flatten(element) : tempArray.push(element);     // ternary check that calls flatten() again if element is an array, hereby making flatten() recursive.
    });
  }

  // calling the inner flatten function, and then returning the temporary array
  flatten(arr);
  return tempArray;
}

// example usage:
let flatArray = flattenArray(nestedArray);

What about using reduce(callback[, initialValue]) method of JavaScript 1.8

list.reduce((p,n) => p.concat(n),[]);

Would do the job.


It can be best done by javascript reduce function.

var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];

arrays = arrays.reduce(function(a, b){
     return a.concat(b);
}, []);

Or, with ES2015:

arrays = arrays.reduce((a, b) => a.concat(b), []);

js-fiddle

Mozilla docs


I was goofing with ES6 Generators the other day and wrote this gist. Which contains...

function flatten(arrayOfArrays=[]){
  function* flatgen() {
    for( let item of arrayOfArrays ) {
      if ( Array.isArray( item )) {
        yield* flatten(item)
      } else {
        yield item
      }
    }
  }

  return [...flatgen()];
}

var flatArray = flatten([[1, [4]],[2],[3]]);
console.log(flatArray);

Basically I'm creating a generator that loops over the original input array, if it finds an array it uses the yield* operator in combination with recursion to continually flatten the internal arrays. If the item is not an array it just yields the single item. Then using the ES6 Spread operator (aka splat operator) I flatten out the generator into a new array instance.

I haven't tested the performance of this, but I figure it is a nice simple example of using generators and the yield* operator.

But again, I was just goofing so I'm sure there are more performant ways to do this.


if you use lodash, you can just use its flatten method: https://lodash.com/docs/4.17.14#flatten

The nice thing about lodash is that it also has methods to flatten the arrays:

i) recursively: https://lodash.com/docs/4.17.14#flattenDeep

ii) upto n levels of nesting: https://lodash.com/docs/4.17.14#flattenDepth

For example

const _ = require("lodash");
const pancake =  _.flatten(array)

let arr = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];
arr = arr.reduce((a, b) => a.concat(b)); // flattened

Since ES2019 has introduced flat and flatMap then flat any array can be done like this:

const myArr = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
const myArrFlat= myArr.flat(Infinity);
console.log(myArrFlat); // ["$6", "$12", "$25", ...]

Ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat


Here is the recursive way...

function flatten(arr){
    let newArray = [];
    for(let i=0; i< arr.length; i++){
        if(Array.isArray(arr[i])){
          newArray =  newArray.concat(flatten(arr[i]))
        }else{
          newArray.push(arr[i])
        }
    }
  return newArray; 
}

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

I recommend a space-efficient generator function:

_x000D_
_x000D_
function* flatten(arr) {_x000D_
  if (!Array.isArray(arr)) yield arr;_x000D_
  else for (let el of arr) yield* flatten(el);_x000D_
}_x000D_
_x000D_
// Example:_x000D_
console.log(...flatten([1,[2,[3,[4]]]])); // 1 2 3 4
_x000D_
_x000D_
_x000D_

If desired, create an array of flattened values as follows:

let flattened = [...flatten([1,[2,[3,[4]]]])]; // [1, 2, 3, 4]

You can just keep on using Array.flat() method to achieve this even when array is a lot more nested.

[1,2,3,[2]].flat() 

is equivalent to

[1,2,3,[2]].flat(1)

so as your nesting increases you can keep on increasing number.

eg:

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

And if you are not sure about level of nesting you can just pass Infinity as parameter

[1,2,3,[2,[3,[3,[34],43],[34]]]].flat(Infinity) //[1, 2, 3, 2, 3, 3, 34, 43, 34]

Here is my version of it. It allows you to flatten a complicated object which could be used in more scenarios:

Input

var input = {
   a: 'asdf',
   b: [1,2,3],
   c: [[1,2],[3,4]],
   d: {subA: [1,2]}
}

Code

The function is like this:

function flatten (input, output) {

  if (isArray(input)) {
    for(var index = 0, length = input.length; index < length; index++){
      flatten(input[index], output);
    }
  }
  else if (isObject(input)) {
    for(var item in input){
      if(input.hasOwnProperty(item)){
        flatten(input[item], output);
      }
    }
  }
  else {
    return output.push(input);
  }
};

function isArray(obj) {
  return Array.isArray(obj) || obj.toString() === '[object Array]';
}

function isObject(obj) {
  return obj === Object(obj);
}

Usage

var output = []

flatten(input, output);

Output

["asdf", 1, 2, 3, 1, 2, 3, 4, 1, 2]


Ways for making flatten array

  • using Es6 flat()
  • using Es6 reduce()
  • using recursion
  • using string manipulation

[1,[2,[3,[4,[5,[6,7],8],9],10]]] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

_x000D_
_x000D_
// using Es6 flat() 
let arr = [1,[2,[3,[4,[5,[6,7],8],9],10]]]
console.log(arr.flat(Infinity))

// using Es6 reduce()
let flatIt = (array) => array.reduce(
  (x, y) => x.concat(Array.isArray(y) ? flatIt(y) : y), []
)
console.log(flatIt(arr))

// using recursion
function myFlat(array) {
  let flat = [].concat(...array);
  return flat.some(Array.isArray) ? myFlat(flat) : flat;
}
console.log(myFlat(arr));

// using string manipulation
let strArr = arr.toString().split(','); 
for(let i=0;i<strArr.length;i++)
  strArr[i]=parseInt(strArr[i]);

console.log(strArr)
_x000D_
_x000D_
_x000D_


Yet another approach using jQuery $.map() function. From jQuery documentation:

The function can return an array of values, which will be flattened into the full array.

var source = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];
var target = $.map(source, function(value) { return value; }); // ["$6", "$12", "$25", "$25", "$18", "$22", "$10"]

If you need to support IE8 and, therefore, can't use methods such as reduce or isArray, here is a possible solution. It is a verbose approach to help you to understand the recursive algorithm.

function flattenArray(a){

    var aFinal = [];

    (function recursiveArray(a){

        var i,
            iCount = a.length;

        if (Object.prototype.toString.call(a) === '[object Array]') {
            for (i = 0; i < iCount; i += 1){
                recursiveArray(a[i]);
            }
        } else {
            aFinal.push(a);
        }

    })(a);

    return aFinal;

}

var aMyArray = [6,3,4,[12,14,15,[23,24,25,[34,35],27,28],56],3,4];

var result = flattenArray(aMyArray);

console.log(result);

var arrays = [["a"], ["b", "c"]];
Array.prototype.concat.apply([], arrays);

// gives ["a", "b", "c"]

(I'm just writing this as a separate answer, based on comment of @danhbear.)


It looks like this looks like a job for RECURSION!

  • Handles multiple levels of nesting
  • Handles empty arrays and non array parameters
  • Has no mutation
  • Doesn't rely on modern browser features

Code:

var flatten = function(toFlatten) {
  var isArray = Object.prototype.toString.call(toFlatten) === '[object Array]';

  if (isArray && toFlatten.length > 0) {
    var head = toFlatten[0];
    var tail = toFlatten.slice(1);

    return flatten(head).concat(flatten(tail));
  } else {
    return [].concat(toFlatten);
  }
};

Usage:

flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7] 

Use this method to flat two arrays

arr1.concat(...arr2);

For Scala users looking for a way to replicate Seq.flatten in Javascript, here is a pimp of Array:

Array.prototype.flatten = function() {
  return [].concat.apply([], this);
};

which can be used this way:

[[12, 3, 5], [1], [], [3, 4]].flatten() // [12, 3, 5, 1, 3, 4]

function flatten(input) {
  let result = [];
  
  function extractArrayElements(input) {
    for(let i = 0; i < input.length; i++){
      if(Array.isArray(input[i])){
        extractArrayElements(input[i]);
      }else{
        result.push(input[i]);
      }
    }
  }
  
  extractArrayElements(input);
  
  return result;
}


// let input = [1,2,3,[4,5,[44,7,8,9]]];
// console.log(flatten(input));

// output [1,2,3,4,5,6,7,8,9]

I would rather transform the whole array, as-is, to a string, but unlike other answers, would do that using JSON.stringify and not use the toString() method, which produce an unwanted result.

With that JSON.stringify output, all that's left is to remove all brackets, wrap the result with start & ending brackets yet again, and serve the result with JSON.parse which brings the string back to "life".

  • Can handle infinite nested arrays without any speed costs.
  • Can rightly handle Array items which are strings containing commas.

_x000D_
_x000D_
var arr = ["abc",[[[6]]],["3,4"],"2"];_x000D_
_x000D_
var s = "[" + JSON.stringify(arr).replace(/\[|]/g,'') +"]";_x000D_
var flattened = JSON.parse(s);_x000D_
_x000D_
console.log(flattened)
_x000D_
_x000D_
_x000D_

  • Only for multidimensional Array of Strings/Numbers (not Objects)

To flatten a two-dimensional array in one line:

[[1, 2], [3, 4, 5]].reduce(Function.prototype.apply.bind(Array.prototype.concat))
// => [ 1, 2, 3, 4, 5 ]

_x000D_
_x000D_
var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];_x000D_
var merged = [].concat.apply([], arrays);_x000D_
alert(merged);
_x000D_
_x000D_
_x000D_


Please note: When Function.prototype.apply ([].concat.apply([], arrays)) or the spread operator ([].concat(...arrays)) is used in order to flatten an array, both can cause stack overflows for large arrays, because every argument of a function is stored on the stack.

Here is a stack-safe implementation in functional style that weighs up the most important requirements against one another:

  • reusability
  • readability
  • conciseness
  • performance

_x000D_
_x000D_
// small, reusable auxiliary functions:_x000D_
_x000D_
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc); // aka reduce_x000D_
_x000D_
const uncurry = f => (a, b) => f(a) (b);_x000D_
_x000D_
const concat = xs => y => xs.concat(y);_x000D_
_x000D_
_x000D_
// the actual function to flatten an array - a self-explanatory one-line:_x000D_
_x000D_
const flatten = xs => foldl(concat) ([]) (xs);_x000D_
_x000D_
// arbitrary array sizes (until the heap blows up :D)_x000D_
_x000D_
const xs = [[1,2,3],[4,5,6],[7,8,9]];_x000D_
_x000D_
console.log(flatten(xs));_x000D_
_x000D_
_x000D_
// Deriving a recursive solution for deeply nested arrays is trivially now_x000D_
_x000D_
_x000D_
// yet more small, reusable auxiliary functions:_x000D_
_x000D_
const map = f => xs => xs.map(apply(f));_x000D_
_x000D_
const apply = f => a => f(a);_x000D_
_x000D_
const isArray = Array.isArray;_x000D_
_x000D_
_x000D_
// the derived recursive function:_x000D_
_x000D_
const flattenr = xs => flatten(map(x => isArray(x) ? flattenr(x) : x) (xs));_x000D_
_x000D_
const ys = [1,[2,[3,[4,[5],6,],7],8],9];_x000D_
_x000D_
console.log(flattenr(ys));
_x000D_
_x000D_
_x000D_

As soon as you get used to small arrow functions in curried form, function composition and higher order functions, this code reads like prose. Programming then merely consists of putting together small building blocks that always work as expected, because they don't contain any side effects.


Just to add to the great solutions. I used recursion to solve this.

            const flattenArray = () => {
                let result = [];
                return function flatten(arr) {
                    for (let i = 0; i < arr.length; i++) {
                        if (!Array.isArray(arr[i])) {
                            result.push(arr[i]);
                        } else {
                            flatten(arr[i])
                        }
                    }
                    return result;
                }
            }

Test results: https://codepen.io/ashermike/pen/mKZrWK


ES6 One Line Flatten

See lodash flatten, underscore flatten (shallow true)

function flatten(arr) {
  return arr.reduce((acc, e) => acc.concat(e), []);
}

or

function flatten(arr) {
  return [].concat.apply([], arr);
}

Tested with

test('already flatted', () => {
  expect(flatten([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats first level', () => {
  expect(flatten([1, [2, [3, [4]], 5]])).toEqual([1, 2, [3, [4]], 5]);
});

ES6 One Line Deep Flatten

See lodash flattenDeep, underscore flatten

function flattenDeep(arr) {
  return arr.reduce((acc, e) => Array.isArray(e) ? acc.concat(flattenDeep(e)) : acc.concat(e), []);
}

Tested with

test('already flatted', () => {
  expect(flattenDeep([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats', () => {
  expect(flattenDeep([1, [2, [3, [4]], 5]])).toEqual([1, 2, 3, 4, 5]);
});

Most of the answers here don't work on huge (e.g. 200 000 elements) arrays, and even if they do, they're slow. polkovnikov.ph's answer has the best performance, but it doesn't work for deep flattening.

Here is the fastest solution, which works also on arrays with multiple levels of nesting:

const flatten = function(arr, result = []) {
  for (let i = 0, length = arr.length; i < length; i++) {
    const value = arr[i];
    if (Array.isArray(value)) {
      flatten(value, result);
    } else {
      result.push(value);
    }
  }
  return result;
};

Examples

Huge arrays

flatten(Array(200000).fill([1]));

It handles huge arrays just fine. On my machine this code takes about 14 ms to execute.

Nested arrays

flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));

It works with nested arrays. This code produces [1, 1, 1, 1, 1, 1, 1, 1].

Arrays with different levels of nesting

flatten([1, [1], [[1]]]);

It doesn't have any problems with flattening arrays like this one.


Recursively calling the deepFlatten function so we can spread the inner array without using any external helper method is the way to go.

const innerArr = ['a', 'b'];
const multiDimArr = [[1, 2], 3, 4, [5, 6, innerArr], 9];

const deepFlatten = (arr) => {
  const flatList = [];
  arr.forEach(item => {
    Array.isArray(item)
     ? flatList.push(...deepFlatten(item)) // recursive call
     : flatList.push(item)
  });
  return flatList;
}

Here is the fastest solution in Typescript, which works also on arrays with multiple levels of nesting:

export function flatten<T>(input: Array<any>, output: Array<T> = []): Array<T> {
    for (const value of input) {
        Array.isArray(value) ? flatten(value, output) : output.push(value);
    }
    return output;
}

and than:

const result = flatten<MyModel>(await Promise.all(promises));

I answer this question just with ES6, assume the deep array is:

const deepArray = ['1',[['a'],['b']],[2],[[[['4',[3,'c']]]],[5]]];

If you know or guess the depth of your arrays is not more than a number like 7, use below code:

const flatArray = deepArray.flat(7);

But if you don't know the depth of your deep arrays or your JavaScript engine doesn't support flat like react-native JavaScriptCore, use below function that is used JavaScript reduce function:

 const deepFlatten = arr =>
         arr.reduce(
           (acc, val) =>
             Array.isArray(val) 
               ? acc.concat(deepFlatten(val)) 
               : acc.concat(val),
             []
         );

Both of methods return below result:

["1", "a", "b", 2, "4", 3, "c", 5]

I was just looking for the faster and easy solution to do this, why? because I get this as a one interview question and I got curious, so I made this:

function flattenArrayOfArrays(a, r){
    if(!r){ r = []}
    for(var i=0; i<a.length; i++){
        if(a[i].constructor == Array){
            flattenArrayOfArrays(a[i], r);
        }else{
            r.push(a[i]);
        }
    }
    return r;
}

var i = [[1,2,[3]],4,[2,3,4,[4,[5]]]], output;

// Start timing now
console.time("flatten");
output = new Array(JSON.stringify(i).replace(/[^\w\s,]/g,"")); 
output
// ... and stop.
console.timeEnd("flatten");

// Start timing now
console.time("flatten2");
output = [].concat.apply([], i)
output
// ... and stop.
console.timeEnd("flatten2");

// Start timing now
console.time("flatten3");
output = flattenArrayOfArrays(i)
output
// ... and stop.
console.timeEnd("flatten3");

I used the most popular answers here and my solution. I guess somebody will find this interesting. Cheers!


Update: it turned out that this solution doesn't work with large arrays. It you're looking for a better, faster solution, check out this answer.


function flatten(arr) {
  return [].concat(...arr)
}

Is simply expands arr and passes it as arguments to concat(), which merges all the arrays into one. It's equivalent to [].concat.apply([], arr).

You can also try this for deep flattening:

function deepFlatten(arr) {
  return flatten(           // return shalowly flattened array
    arr.map(x=>             // with each x in array
      Array.isArray(x)      // is x an array?
        ? deepFlatten(x)    // if yes, return deeply flattened x
        : x                 // if no, return just x
    )
  )
}

See demo on JSBin.

References for ECMAScript 6 elements used in this answer:


Side note: methods like find() and arrow functions are not supported by all browsers, but it doesn't mean that you can't use these features right now. Just use Babel — it transforms ES6 code into ES5.


Generic procedures mean we don't have to rewrite complexity each time we need to utilize a specific behaviour.

concatMap (or flatMap) is exactly what we need in this situation.

_x000D_
_x000D_
// concat :: ([a],[a]) -> [a]_x000D_
const concat = (xs,ys) =>_x000D_
  xs.concat (ys)_x000D_
_x000D_
// concatMap :: (a -> [b]) -> [a] -> [b]_x000D_
const concatMap = f => xs =>_x000D_
  xs.map(f).reduce(concat, [])_x000D_
_x000D_
// id :: a -> a_x000D_
const id = x =>_x000D_
  x_x000D_
_x000D_
// flatten :: [[a]] -> [a]_x000D_
const flatten =_x000D_
  concatMap (id)_x000D_
_x000D_
// your sample data_x000D_
const data =_x000D_
  [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]_x000D_
_x000D_
console.log (flatten (data))
_x000D_
_x000D_
_x000D_

foresight

And yes, you guessed it correctly, it only flattens one level, which is exactly how it should work

Imagine some data set like this

_x000D_
_x000D_
// Player :: (String, Number) -> Player_x000D_
const Player = (name,number) =>_x000D_
  [ name, number ]_x000D_
_x000D_
// team :: ( . Player) -> Team_x000D_
const Team = (...players) =>_x000D_
  players_x000D_
_x000D_
// Game :: (Team, Team) -> Game_x000D_
const Game = (teamA, teamB) =>_x000D_
  [ teamA, teamB ]_x000D_
_x000D_
// sample data_x000D_
const teamA =_x000D_
  Team (Player ('bob', 5), Player ('alice', 6))_x000D_
_x000D_
const teamB =_x000D_
  Team (Player ('ricky', 4), Player ('julian', 2))_x000D_
_x000D_
const game =_x000D_
  Game (teamA, teamB)_x000D_
_x000D_
console.log (game)_x000D_
// [ [ [ 'bob', 5 ], [ 'alice', 6 ] ],_x000D_
//   [ [ 'ricky', 4 ], [ 'julian', 2 ] ] ]
_x000D_
_x000D_
_x000D_

Ok, now say we want to print a roster that shows all the players that will be participating in game

const gamePlayers = game =>
  flatten (game)

gamePlayers (game)
// => [ [ 'bob', 5 ], [ 'alice', 6 ], [ 'ricky', 4 ], [ 'julian', 2 ] ]

If our flatten procedure flattened nested arrays too, we'd end up with this garbage result …

const gamePlayers = game =>
  badGenericFlatten(game)

gamePlayers (game)
// => [ 'bob', 5, 'alice', 6, 'ricky', 4, 'julian', 2 ]

rollin' deep, baby

That's not to say sometimes you don't want to flatten nested arrays, too – only that shouldn't be the default behaviour.

We can make a deepFlatten procedure with ease …

_x000D_
_x000D_
// concat :: ([a],[a]) -> [a]_x000D_
const concat = (xs,ys) =>_x000D_
  xs.concat (ys)_x000D_
_x000D_
// concatMap :: (a -> [b]) -> [a] -> [b]_x000D_
const concatMap = f => xs =>_x000D_
  xs.map(f).reduce(concat, [])_x000D_
_x000D_
// id :: a -> a_x000D_
const id = x =>_x000D_
  x_x000D_
_x000D_
// flatten :: [[a]] -> [a]_x000D_
const flatten =_x000D_
  concatMap (id)_x000D_
_x000D_
// deepFlatten :: [[a]] -> [a]_x000D_
const deepFlatten =_x000D_
  concatMap (x =>_x000D_
    Array.isArray (x) ? deepFlatten (x) : x)_x000D_
_x000D_
// your sample data_x000D_
const data =_x000D_
  [0, [1, [2, [3, [4, 5], 6]]], [7, [8]], 9]_x000D_
_x000D_
console.log (flatten (data))_x000D_
// [ 0, 1, [ 2, [ 3, [ 4, 5 ], 6 ] ], 7, [ 8 ], 9 ]_x000D_
_x000D_
console.log (deepFlatten (data))_x000D_
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
_x000D_
_x000D_
_x000D_

There. Now you have a tool for each job – one for squashing one level of nesting, flatten, and one for obliterating all nesting deepFlatten.

Maybe you can call it obliterate or nuke if you don't like the name deepFlatten.


Don't iterate twice !

Of course the above implementations are clever and concise, but using a .map followed by a call to .reduce means we're actually doing more iterations than necessary

Using a trusty combinator I'm calling mapReduce helps keep the iterations to a minium; it takes a mapping function m :: a -> b, a reducing function r :: (b,a) ->b and returns a new reducing function - this combinator is at the heart of transducers; if you're interested, I've written other answers about them

_x000D_
_x000D_
// mapReduce = (a -> b, (b,a) -> b, (b,a) -> b)_x000D_
const mapReduce = (m,r) =>_x000D_
  (acc,x) => r (acc, m (x))_x000D_
_x000D_
// concatMap :: (a -> [b]) -> [a] -> [b]_x000D_
const concatMap = f => xs =>_x000D_
  xs.reduce (mapReduce (f, concat), [])_x000D_
_x000D_
// concat :: ([a],[a]) -> [a]_x000D_
const concat = (xs,ys) =>_x000D_
  xs.concat (ys)_x000D_
_x000D_
// id :: a -> a_x000D_
const id = x =>_x000D_
  x_x000D_
_x000D_
// flatten :: [[a]] -> [a]_x000D_
const flatten =_x000D_
  concatMap (id)_x000D_
  _x000D_
// deepFlatten :: [[a]] -> [a]_x000D_
const deepFlatten =_x000D_
  concatMap (x =>_x000D_
    Array.isArray (x) ? deepFlatten (x) : x)_x000D_
_x000D_
// your sample data_x000D_
const data =_x000D_
  [ [ [ 1, 2 ],_x000D_
      [ 3, 4 ] ],_x000D_
    [ [ 5, 6 ],_x000D_
      [ 7, 8 ] ] ]_x000D_
_x000D_
console.log (flatten (data))_x000D_
// [ [ 1. 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]_x000D_
_x000D_
console.log (deepFlatten (data))_x000D_
// [ 1, 2, 3, 4, 5, 6, 7, 8 ]
_x000D_
_x000D_
_x000D_


/**
* flatten an array first level
* @method flatten
* @param array {Array}
* @return {Array} flatten array
*/
function flatten(array) {
  return array.reduce((acc, current) => acc.concat(current), []);
}


/**
* flatten an array recursively
* @method flattenDeep
* @param array {Array}
* @return {Array} flatten array
*/
function flattenDeep(array) {
  return array.reduce((acc, current) => {
    return Array.isArray(current) ? acc.concat(flattenDeep(current)) : acc.concat([current]);
  }, []);
}

/**
* flatten an array recursively limited by depth
* @method flattenDepth
* @param array {Array}
* @return {Array} flatten array
*/
function flattenDepth(array, depth) {
  if (depth === 0) {
    return array;
  }
  return array.reduce((acc, current) => {
    return Array.isArray(current) ? acc.concat(flattenDepth(current, --depth)) : acc.concat([current]);
  }, []);
}

There is a confusingly hidden method, which constructs a new array without mutating the original one:

_x000D_
_x000D_
var oldArray = [[1],[2,3],[4]];_x000D_
var newArray = Array.prototype.concat.apply([], oldArray);_x000D_
console.log(newArray); // [ 1, 2, 3, 4 ]
_x000D_
_x000D_
_x000D_


Define an array of arrays in javascript called foo and flatten that array of arrays into a single array using javascript's array concat builtin method:

const foo = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]] 
console.log({foo}); 

const bar = [].concat(...foo) 
console.log({bar});

Should print:

{ foo: 
   [ [ '$6' ],
     [ '$12' ],
     [ '$25' ],
     [ '$25' ],
     [ '$18' ],
     [ '$22' ],
     [ '$10' ] ] }
{ bar: [ '$6', '$12', '$25', '$25', '$18', '$22', '$10' ] }

Nowadays the best and easy way to do this is joining and spliting the array like this.

var multipleArrays = [["$6","$Demo"], ["$12",["Multi","Deep"]], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]]

var flattened = multipleArrays.join().split(",")

This solution works with multiple levels and is also oneliner.

DEMO

EDIT for ECMAScript 6

Since ECMAScript 6 has been standardized, you can change the operation [].concat.apply([], arrays); for [].concat(...arrays);

var flattened = [].concat(...input);

DEMO

EDIT Most Efficient solution

The most efficient way to solve the problem is using a loop. You can compare the "ops/sec" velocity here

var flattened=[];
for (var i=0; i<input.length; ++i) {
    var current = input[i];
    for (var j=0; j<current.length; ++j)
        flattened.push(current[j]);
} 

DEMO

Hope It Helps


I think array.flat(Infinity) is a perfect solution. But flat function is a relatively new function and may not run in older versions of browsers. We can use recursive function for solving this.

_x000D_
_x000D_
const arr = ["A", ["B", [["B11", "B12", ["B131", "B132"]], "B2"]], "C", ["D", "E", "F", ["G", "H", "I"]]]_x000D_
const flatArray = (arr) => {_x000D_
    const res = []_x000D_
    for (const item of arr) {_x000D_
        if (Array.isArray(item)) {_x000D_
            const subRes = flatArray(item)_x000D_
            res.push(...subRes)_x000D_
        } else {_x000D_
            res.push(item)_x000D_
        }_x000D_
    }_x000D_
_x000D_
    return res_x000D_
}_x000D_
_x000D_
console.log(flatArray(arr))
_x000D_
_x000D_
_x000D_


I propose two short solutions without recursion. They are not optimal from a computational complexity point of view, but work fine in average cases:

let a = [1, [2, 3], [[4], 5, 6], 7, 8, [9, [[10]]]];

// Solution #1
while (a.find(x => Array.isArray(x)))
    a = a.reduce((x, y) => x.concat(y), []);

// Solution #2
let i = a.findIndex(x => Array.isArray(x));
while (i > -1)
{
    a.splice(i, 1, ...a[i]);
    i = a.findIndex(x => Array.isArray(x));
}

I'm aware that this is hacky, but the must succinct way I know of to flatten an array(of any depth!) of strings(without commas!) is to turn the array into a string and then split the string on commas:

var myArray =[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];
var myFlatArray = myArray.toString().split(',');

myFlatArray;
// ["$6", "$12", "$25", "$25", "$18", "$22", "$10", "$0", "$15", "$3", "$75", "$5", "$100", "$7", "$3", "$75", "$5"]

This should work on any depth of nested arrays containing only strings and numbers(integers and floating points) with the caveat that numbers will be converted to strings in the process. This can be solved with a little mapping:

var myArray =[[[1,2],[3,4]],[[5,6],[7,8]],[[9,0]]];
var myFlatArray = myArray.toString().split(',').map(function(e) { return parseInt(e); });
myFlatArray;
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

I have done it using recursion and closures

function flatten(arr) {

  var temp = [];

  function recursiveFlatten(arr) { 
    for(var i = 0; i < arr.length; i++) {
      if(Array.isArray(arr[i])) {
        recursiveFlatten(arr[i]);
      } else {
        temp.push(arr[i]);
      }
    }
  }
  recursiveFlatten(arr);
  return temp;
}

This solution will work for any depth level (specifying how deep a nested array structure should be) of array.

function flatten(obj) {
    var out = [];
    function cleanElements(input) {
        for (var i  in input){
            if (input[i]instanceof Array){
                cleanElements(input[i]);
            }
            else {
                out.push(input[i]);
            }
        }
    }
    cleanElements(obj);
    return (out);
}