我有一个JavaScript数组,如:

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

如何将单独的内部数组合并为一个,例如:

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

当前回答

我只使用ES6回答这个问题,假设深度阵列是:

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

如果您知道或猜测阵列的深度不超过7这样的数字,请使用以下代码:

const flatArray = deepArray.flat(7);

但如果你不知道深度数组的深度,或者你的JavaScript引擎不支持像react原生JavaScriptCore那样的flat,请使用下面的JavaScript reduce函数:

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

这两种方法都返回以下结果:

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

其他回答

使用排列运算符:

常量输入=[[“$6”],[“$12”],【“$25”】,[“$25“],【”$18“】,【”$22“】,[”$10“]];常量输出=[].contat(…输入);console.log(输出);//-->["$6", "$12", "$25", "$25", "$18", "$22", "$10"]

现在,实现这一点的最佳且简单的方法是这样连接和拆分阵列。

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(",")

此解决方案适用于多个级别,也是一个线性解决方案。

DEMO

ECMAScript 6的EDIT

由于ECMAScript 6已经标准化,您可以更改操作[].contat.apply([],arrays);对于[].contat(…数组);

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

DEMO

EDIT最高效的解决方案

解决这个问题最有效的方法是使用循环。您可以在此处比较“ops/sec”速度

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

希望有帮助

泛型过程意味着我们不必在每次需要利用特定行为时重写复杂性。

concatMap(或flatMap)正是我们在这种情况下需要的。

//凹面::([a],[a])->[a]常量concat=(xs,ys)=>xs.concat(系统)//concatMap::(a->[b])->[a]->[b】常量concatMap=f=>xs=>xs.map(f).reduce(concat,[])//id::a->a常量id=x=>x(x)//展平::[[a]]->[a]常量展平=concatMap(id)//您的示例数据常量数据=[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]console.log(展平(数据))

远见

是的,你猜对了,它只会使一个层次变平,这正是它应该工作的方式

想象一下这样的数据集

//玩家::(字符串,数字)->玩家常量玩家=(姓名,号码)=>[姓名、编号]//team::(.Player)->团队const团队=(…玩家)=>玩家//游戏::(团队,团队)->游戏常量游戏=(teamA,teamB)=>[团队A,团队B]//样本数据常量团队A=团队(球员('ob',5),球员('lice',6))常量组B=团队(球员(“恶心”,4),球员(“朱利安”,2))常量游戏=游戏(A队、B队)console.log(游戏)//[[鲍勃,5],[爱丽丝,6],//[['ricky',4],['julian',2]]]

好的,现在假设我们要打印一份名册,显示所有将参加比赛的球员…

const gamePlayers = game =>
  flatten (game)

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

如果我们的展平过程也展平了嵌套数组,我们最终会得到这个垃圾结果…

const gamePlayers = game =>
  badGenericFlatten(game)

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

滚得很深,宝贝

这并不是说有时候你也不想压平嵌套的数组——只是这不应该是默认行为。

我们可以轻松地制作一个deepFlatten程序…

//凹面::([a],[a])->[a]常量concat=(xs,ys)=>xs.concat(系统)//concatMap::(a->[b])->[a]->[b】常量concatMap=f=>xs=>xs.map(f).reduce(concat,[])//id::a->a常量id=x=>x(x)//展平::[[a]]->[a]常量展平=concatMap(id)//deepFlatten::[[a]]->[a]恒定深度展平=凹面贴图(x=>Array.isArray(x)?深度展平(x):x)//您的示例数据常量数据=[0, [1, [2, [3, [4, 5], 6]]], [7, [8]], 9]console.log(展平(数据))// [ 0, 1, [ 2, [ 3, [ 4, 5 ], 6 ] ], 7, [ 8 ], 9 ]console.log(deepFlatten(数据))// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

那里现在,每个作业都有一个工具——一个用于挤压一层嵌套、展平,另一个用于清除所有嵌套深度展平。

如果你不喜欢deepFlatten这个名字,也许你可以称之为毁灭或核武器。


不要重复两次!

当然,上面的实现是聪明和简洁的,但是使用.map后跟.reduce的调用意味着我们实际上要做的迭代超过了需要

使用我称之为mapReduce的可靠组合器,可以帮助将迭代保持在最小值;它采用一个映射函数m::a->b,一个归约函数r::(b,a)->b,并返回一个新的归约函数-这个组合子是换能器的核心;如果你感兴趣,我已经写了其他关于他们的答案

//mapReduce=(a->b,(b,a)->b,(a,b)->b)常量mapReduce=(m,r)=>(加速度,x)=>r(加速度,m(x))//concatMap::(a->[b])->[a]->[b】常量concatMap=f=>xs=>xs.reduce(mapReduce(f,concat),[])//凹面::([a],[a])->[a]常量concat=(xs,ys)=>xs.concat(系统)//id::a->a常量id=x=>x(x)//展平::[[a]]->[a]常量展平=concatMap(id)//deepFlatten::[[a]]->[a]恒定深度展平=凹面贴图(x=>Array.isArray(x)?深度展平(x):x)//您的示例数据常量数据=[ [ [ 1, 2 ],[ 3, 4 ] ],[ [ 5, 6 ],[ 7, 8 ] ] ]console.log(展平(数据))// [ [ 1. 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]console.log(deepFlatten(数据))// [ 1, 2, 3, 4, 5, 6, 7, 8 ]

Haskell式方法

函数flatArray([x,…xs]){返回x?[…Array.isArray(x)?flatArray(x):[x]。。。flatArray(xs)]:[];}var na=[[1,2],[3,[4,5]],[6,7,[[[8],9],10];fa=平面阵列(na);console.log(fa);

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

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

我使用了这里最流行的答案和我的解决方案。我想有人会觉得这很有趣。干杯