在JavaScript中合并/拼合数组数组?

out 发布于 2019-01-15 arrays 最后更新 2019-01-15 12:51 208 浏览

我有一个JavaScript数组,如:

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
我将如何去做这件事:
["$6", "$12", "$25", ...]
已邀请:

kquis

赞同来自:

我只是在寻找更快更简单的解决方案,为什么?因为我把这作为一个面试问题,我很好奇,所以我做了这个:

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");
我在这里使用了最流行的答案和我的解决方案。我想有人会发现这很有趣。干杯!

modit

赞同来自:

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

yut

赞同来自:

您可以使用Underscore

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

lquia

赞同来自:

只是没有lodash的最佳解决方案

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

vvel

赞同来自:

我原本以为使用.reduce方法并递归调用函数来展平内部数组,但是当您使用深度嵌套数组的深层嵌套数组时,这会导致堆栈溢出。使用concat也不是最好的方法,因为每次迭代都会创建一个新的数组浅表副本。我们可以做的是:

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;
}
我们不是通过concat创建新数组,我们不是递归调用任何函数。 http://jsbin.com/firiru/4/edit?js,console

nodio

赞同来自:

假设您的数组数组存储在obj中。 我们将最终输出存储在obj1中。 javascript中的简单方法是:

for(var i=0;i<obj.length;i++) 
  for(var j =0;j<obj[i].length;j++) 
    obj1.push(obj[i][j]);
这是节点控制台上的代码输出。
> var obj=[];
undefined
> obj=[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]]
[ [ '$6' ],
  [ '$12' ],
  [ '$25' ],
  [ '$25' ],
  [ '$18' ],
  [ '$22' ],
  [ '$10' ],
  [ '$0' ],
  [ '$15' ],
  [ '$3' ],
  [ '$75' ],
  [ '$5' ],
  [ '$100' ],
  [ '$7' ],
  [ '$3' ],
  [ '$75' ],
  [ '$5' ] ]
> var obj1=[];
undefined
> for(var i=0;i<obj.length;i++) for(var j =0;j<obj[i].length;j++) obj1.push(obj[i][j]);
17
> obj1
[ '$6',
  '$12',
  '$25',
  '$25',
  '$18',
  '$22',
  '$10',
  '$0',
  '$15',
  '$3',
  '$75',
  '$5',
  '$100',
  '$7',
  '$3',
  '$75',
  '$5' ]
> 

snon

赞同来自:

您可以使用Array.prototype.reduce()Array.prototype.concat()展平数组数组

var data = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]].reduce(function(a, b) {
  return a.concat(b);
}, []);
console.log(data);
相关文档: 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

eut

赞同来自:

我建议两个没有递归的简短解决方案。从计算复杂性的角度来看,它们并不是最优的,但在平均情况下工作正常:

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));
}

onam

赞同来自:

功能风格的另一个ECMAScript 6解决方案: 声明功能:

const flatten = arr => arr.reduce(
  (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
);
并使用它:
flatten( [1, [2,3], [4,[5,[6]]]] ) // -> [1,2,3,4,5,6]

ramet

赞同来自:

尝试这个 : var arrays = [[“$ 6”],[“$ 12”],[“$ 25”],[“$ 25”],[“$ 18”],[“$ 22”],[“$ 10”]]; var data = [] .concat.apply([],arrays); var finalresults = [] .concat([“$ 6”],[“$ 12”],[“$ 25”],[“$ 25”],[“$ 18”],[“$ 22”],[“$ 10”]) ;

overo

赞同来自:

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

lenim

赞同来自:

我相信最好的方法是这样的:

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

dut

赞同来自:

最好通过javascript reduce函数来完成。

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);
}, []);
或者,使用ES2015:
arrays = arrays.reduce((a, b) => a.concat(b), []);
js-fiddle Mozilla docs

xet

赞同来自:

使用JavaScript 1.8reduce(callback[, initialValue])方法怎么样?

list.reduce( function( p,n){
    return p.concat( n  );
},[]);

funde

赞同来自:

如果只有1个字符串元素的数组:

[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');
会做的。 Bt特别匹配您的代码示例。

walias

赞同来自:

我宁愿将整个数组按原样转换为字符串,但与其他答案不同,使用JSON.stringify并不使用toString()方法,这会产生不需要的结果。 使用该JSON.stringify输出,剩下的就是删除所有括号,用start& amp;再次结束括号,并使用JSON.parse将结果提供给“生命”。

  • 无需任何速度成本即可处理无限嵌套数组。
  • 可以正确处理包含逗号的字符串的数组项。

var arr = ["abc",[[[6]]],["3,4"],"2"];
var s = "[" + JSON.stringify(arr).replace(/\[|]/g,'') +"]";
var flattened = JSON.parse(s);
console.log(flattened)
  • 仅适用于多维数组字符串/数字(不是对象)

id_sed

赞同来自:

一种Haskellesque方法

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

cea

赞同来自:

看起来这看起来像是RECURSION的工作!

  • 处理多个嵌套级别
  • 处理空数组和非数组参数
  • 没有变异
  • 不依赖于现代浏览器功能
码:
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);
  }
};
用法:
flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7] 

lest

赞同来自:

深层压扁怎么样?面向对象?
[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
如果所有数组元素都是Integer,Float,...或/和String,那么就这样做吧:
var myarr=[1,[7,[9.2]],[3],90];
eval('myarr=['+myarr.toString()+']');
print(myarr);
// [1, 7, 9.2, 3, 90]

DEMO

verror

赞同来自:

前几天我和PLACEHOLDER_FOR_CODE_一起玩,并写了this gist。其中包含...

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);
基本上我正在创建一个循环在原始输入数组上的生成器,如果它找到一个数组,它会使用yield*运算符和递归来连续展平内部数组。如果该项目不是数组,则只需yields单项。然后使用ES6 Spread operator(又名splat运算符),我将生成器展平为一个新的数组实例。 我没有测试过它的性能,但我认为它是使用生成器和yield *运算符的一个很好的简单例子。 但同样,我只是在玩弄,所以我确信有更多高效的方法可以做到这一点。

jneque

赞同来自:

const flattenArray = myArray => (myArray.toString().split(','));
console.log(flattenArray([["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]));

caut

赞同来自:

对于更一般的情况的解决方案,当您的数组中可能有一些非数组元素时。

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;
}

oenim

赞同来自:

这是一个简单而高效的功能解决方案:

var result = [].concat.apply([], [[1],[2,3],[4]]);
console.log(result); // [ 1, 2, 3, 4 ]
没有必要的混乱。

rsaepe

赞同来自:

以下代码将展平深层嵌套数组:

/**
 * [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 ]

jautem

赞同来自:

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]].flatten();

ha

赞同来自:

这是现代浏览器的另一个深度扁平化:

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

lnulla

赞同来自:

请注意:当使用Function.prototype.apply([].concat.apply([], arrays))或扩展运算符([].concat(...arrays))来展平数组时,两者都会导致大型数组的堆栈溢出,因为函数的每个参数都存储在堆栈中。 这是一个功能样式的堆栈安全实现,它重叠了彼此最重要的要求:

  • 可重用性
  • 可读性
  • 简明
  • 性能
// small, reusable auxiliary functions:
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc); // aka reduce
const uncurry = f => (a, b) => f(a) (b);
const concat = xs => y => xs.concat(y);
// the actual function to flatten an array - a self-explanatory one-line:
const flatten = xs => foldl(concat) ([]) (xs);
// arbitrary array sizes (until the heap blows up :D)
const xs = [[1,2,3],[4,5,6],[7,8,9]];
console.log(flatten(xs));
// Deriving a recursive solution for deeply nested arrays is trivially now
// yet more small, reusable auxiliary functions:
const map = f => xs => xs.map(apply(f));
const apply = f => a => f(a);
const isArray = Array.isArray;
// the derived recursive function:
const flattenr = xs => flatten(map(x => isArray(x) ? flattenr(x) : x) (xs));
const ys = [1,[2,[3,[4,[5],6,],7],8],9];
console.log(flattenr(ys));
一旦习惯了咖喱形式,函数组合和高阶函数的小箭头函数,这段代码就像散文一样。然后,编程只需要将总是按预期工作的小构建块放在一起,因为它们不包含任何副作用。

et_et

赞同来自:

这里的逻辑是将输入数组转换为字符串并删除所有括号([])并将输出解析为数组。我正在使用ES6模板功能。

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)

mut

赞同来自:

我推荐一个节省空间的generator function

function* flatten(arr) {
  if (!Array.isArray(arr)) yield arr;
  else for (let el of arr) yield* flatten(el);
}
// Example:
console.log(...flatten([1,[2,[3,[4]]]])); // 1 2 3 4
如果需要,创建一个展平值数组,如下所示:
let flattened = [...flatten([1,[2,[3,[4]]]])]; // [1, 2, 3, 4]

matque

赞同来自:

const flatten = array => array.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []); 
按要求,分解一行基本上就是这个。
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
}

gquia

赞同来自:

这里的大多数答案不适用于巨大的(例如200 000个元素)阵列,即使它们这样做,它们也很慢。 polkovnikov.ph's answer具有最佳性能,但它不适用于深度展平。 这是最快的解决方案,它也适用于具有多级嵌套的数组:

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;
};
我认为不需要解释;任何具有JavaScript基础知识的人都应该能够理解它。

实施例

巨大阵列
flatten(Array(200000).fill([1]));
它处理大型数组就好了。在我的机器上,这段代码需要大约30毫秒才能执行。

嵌套数组
flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));
它适用于嵌套数组。此代码生成[1, 1, 1, 1, 1, 1, 1, 1]

具有不同嵌套级别的数组
flatten([1, [1], [[1]]]);
像这样平整数组没有任何问题。

uanimi

赞同来自:

var arrays = [["a"], ["b", "c"]];
Array.prototype.concat.apply([], arrays);
// gives ["a", "b", "c"]
(我只是根据@danhbear的评论将其作为一个单独的答案。)

verror

赞同来自:

要展平2个阵列,您还可以使用此array-flatMap开源组件。它通过将函数应用于此数组的所有元素并使用生成的集合的元素来构建新集合。 例:

 flatMap([[1, 2, 3], [4, 5, 6]], val => val) // => [1, 2, 3, 4, 5, 6]

tin

赞同来自:

适用于所有数据类型的递归版本

 /*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);

uautem

赞同来自:

现在,最好和最简单的方法是像这样加入和分割数组。

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(",")
此解决方案适用于多个级别,也是oneliner。 DEMO 编辑ECMAScript 6 由于ECMAScript 6已标准化,您可以为[].concat(...arrays);更改操作[].concat.apply([], arrays);
var flattened = [].concat(...input);
DEMO 编辑最有效的解决方案 解决问题的最有效方法是使用循环。您可以比较“ops / sec”速度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 希望能帮助到你

iut

赞同来自:

这是一个简短的函数,它使用一些较新的JavaScript数组方法来展平n维数组。

function flatten(arr) {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
  }, []);
}
用法:
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]

xhic

赞同来自:

这是我的版本。它允许您展平可在更多场景中使用的复杂对象: 输入

var input = {
   a: 'asdf',
   b: [1,2,3],
   c: [[1,2],[3,4]],
   d: {subA: [1,2]}
}
码 功能是这样的:
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);
}
用法
var output = []
flatten(input, output);
产量 [“asdf”,1,2,3,1,2,3,4,1,2]

uqui

赞同来自:

更新:事实证明,此解决方案不适用于大型阵列。您正在寻找更好,更快的解决方案,请查看this answer


function flatten(arr) {
  return [].concat(...arr)
}
只需展开arr并将其作为参数传递给concat(),后者将所有数组合并为一个。它相当于[].concat.apply([], arr)。 你也可以试试深度压扁:
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
    )
  )
}
请参阅JSBin上的演示。 本答案中使用的ECMAScript 6元素的参考:
附注:所有浏览器都不支持find()和箭头功能等方法,但这并不意味着您现在无法使用这些功能。只需使用Babel - 它将ES6代码转换为ES5。

frem

赞同来自:

我知道这是hacky,但我必须简洁的方法来展平一个数组(任何深度!)的字符串(没有逗号!)是将数组转换为字符串,然后在逗号上拆分字符串:

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"]
这应该适用于任何深度的嵌套数组,只包含字符串和数字(​​整数和浮点),但需要注意的是数字将在过程中转换为字符串。这可以通过一点映射来解决:
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]

zomnis

赞同来自:

/**
* flatten an array first level
* @method flatten
* @param array {Array}
* @return {Array} flatten array
*/
function flatten(array) {
  return array.reduce((acc, current) => {
    return Array.isArray(current) ? acc.concat(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]);
  }, []);
}

zomnis

赞同来自:

如果你的数组只包含整数或字符串,你可以使用这个脏的黑客:

var arr = [345,2,[34],2,[524,[5456]],[5456]];
var flat = arr.toString().split(',');
在FF,IE和Chrome中的作品尚未测试其他浏览器。

dodit

赞同来自:

使用there中的代码。 我会写:

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

ueum

赞同来自:

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

xesse

赞同来自:

当扁平化不深时,我没有在这里找到大阵列的解决方案。所以,我的版本:

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

et_ea

赞同来自:

通用程序意味着每次我们需要利用特定行为时,我们不必重写复杂性。 concatMap(或flatMap)正是我们在这种情况下所需要的。

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

远见 是的,你猜对了,它只会使一个级别变平,这正是它应该如何工作的 想象一下像这样的一些数据集
// Player :: (String, Number) -> Player
const Player = (name,number) =>
  [ name, number ]
// team :: ( . Player) -> Team
const Team = (...players) =>
  players
// Game :: (Team, Team) -> Game
const Game = (teamA, teamB) =>
  [ teamA, teamB ]
// sample data
const teamA =
  Team (Player ('bob', 5), Player ('alice', 6))
const teamB =
  Team (Player ('ricky', 4), Player ('julian', 2))
const game =
  Game (teamA, teamB)
console.log (game)
// [ [ [ 'bob', 5 ], [ 'alice', 6 ] ],
//   [ [ 'ricky', 4 ], [ 'julian', 2 ] ] ]
好的,现在说我们要打印一个名单,显示将参加game&hellip的所有玩家;
const gamePlayers = game =>
  flatten (game)
gamePlayers (game)
// => [ [ 'bob', 5 ], [ 'alice', 6 ], [ 'ricky', 4 ], [ 'julian', 2 ] ]
如果我们的flatten程序也使嵌套数组变平,我们最终会得到这个垃圾结果…
const gamePlayers = game =>
  badGenericFlatten(game)
gamePlayers (game)
// => [ 'bob', 5, 'alice', 6, 'ricky', 4, 'julian', 2 ]

罗林'深,宝贝 这并不是说有时候你也不想压扁嵌套数组 - 只是不应该是默认行为。 我们可以轻松制作deepFlatten程序…
// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.map(f).reduce(concat, [])
// id :: a -> a
const id = x =>
  x
// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)
// deepFlatten :: [[a]] -> [a]
const deepFlatten =
  concatMap (x =>
    Array.isArray (x) ? deepFlatten (x) : x)
// your sample data
const data =
  [0, [1, [2, [3, [4, 5], 6]]], [7, [8]], 9]
console.log (flatten (data))
// [ 0, 1, [ 2, [ 3, [ 4, 5 ], 6 ] ], 7, [ 8 ], 9 ]
console.log (deepFlatten (data))
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
那里。现在,每个作业都有一个工具 - 一个用于压缩一个嵌套级别,flatten,另一个用于清除所有嵌套deepFlatten。 如果您不喜欢名称deepFlatten,也许可以将其称为obliteratenuke
不要迭代两次! 当然上面的实现是聪明和简洁的,但是使用.map然后调用.reduce意味着我们实际上做了比必要更多的迭代 使用可信赖的组合器,我称之为mapReduce有助于将迭代保持在最小值;它需要一个映射函数m :: a -> b,一个减少函数r :: (b,a) ->b并返回一个新的减少函数 - 这个组合器是传感器的核心;如果你有兴趣,请I've written other answers about them
// mapReduce = (a -> b, (b,a) -> b, (b,a) -> b)
const mapReduce = (m,r) =>
  (acc,x) => r (acc, m (x))
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.reduce (mapReduce (f, concat), [])
// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)
// id :: a -> a
const id = x =>
  x
// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)
// deepFlatten :: [[a]] -> [a]
const deepFlatten =
  concatMap (x =>
    Array.isArray (x) ? deepFlatten (x) : x)
// your sample data
const data =
  [ [ [ 1, 2 ],
      [ 3, 4 ] ],
    [ [ 5, 6 ],
      [ 7, 8 ] ] ]
console.log (flatten (data))
// [ [ 1. 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]
console.log (deepFlatten (data))
// [ 1, 2, 3, 4, 5, 6, 7, 8 ]

sunde

赞同来自:

我已经使用递归和闭包完成了它

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;
}

snon

赞同来自:

你能试试这个:

[].concat.apply([], myArray);

lest

赞同来自:

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

mut

赞同来自:

要在一行中展平二维数组:

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

et_qui

赞同来自:

如果您需要支持IE8,因此无法使用reduce或isArray等方法,这里有一个可能的解决方案。这是一个冗长的方法来帮助您理解递归算法。

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);

eomnis

赞同来自:

有一种比使用顶部答案中列出的merge.concat.apply()方法更快的方法,并且速度更快,我的意思是快几个数量级。这假设您的环境可以访问ES5 Array方法。

var array2d = [
  ["foo", "bar"],
  ["baz", "biz"]
];
merged = array2d.reduce(function(prev, next) {
    return prev.concat(next);
});
这是jsperf链接:http://jsperf.com/2-dimensional-array-merge

ivel

赞同来自:

您可以使用concat合并数组:

var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];
var merged = [].concat.apply([], arrays);
使用concatapply方法只会将第二个参数作为数组,因此最后一行与此相同:
var merged2 = [].concat(["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]);

bquos

赞同来自:

要展平单个元素数组的数组,您不需要导入库,简单循环是最简单的most efficient解决方案:

for (var i = 0; i < a.length; i++) {
  a[i] = a[i][0];
}
对于downvoters:请阅读问题,不要贬低,因为它不适合你非常不同的问题。对于问题,这个解决方案既是最快也最简单的。

laut

赞同来自:

这并不难,只需遍历数组并合并它们:

var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];
for (var i = 0; i < input.length; ++i) {
    result = result.concat(input[i]);
}