更高效/更聪明的方式,以特定的方式对multidimensional array进行分组/压缩

我有一个多维的数组,我不知道它的大小,我知道的是每个孩子将有相同的长度和相同的结构。

我需要连接第一个孩子的内部数组与同胞的内部数组,所以所有孩子相同的索引内部数组在一个数组中。

(如果有人想说得更好一些,或者改进标题,那就成为我的客人吧)

例:

let arrays = [ //1 [[1, 2], [3, 4], [5, 6]], //2 [[10, 20], [30, 40], [50, 60]], //3 [[100, 200], [300, 400], [500, 600]], //N [[10000, 20000], [30000, 40000], [50000, 60000]], ]; 

预期结果:

 [ [1, 2, 10, 20, 100, 200, 10000, 20000], [3, 4, 30, 40, 300, 400, 30000, 40000], [5, 6, 50, 60, 500, 600, 50000, 60000] ] 

这是我目前正在做的,这是工作,但这是一个矫枉过正。

 /** * Helper function * Will return all the values at ${index} of each array in ${arrays} * Example: index(1, [[1,2], [3,4]]); //[2, 4] */ function index(index, arrays){ let results = []; for(let i = 0, len = arrays.length; i < len; i++) results.push(arrays[i][index]); return results; } let first = arrays.shift(); let output = first.map((item, i) => item.concat( ...index(i, arrays) )) 

我正在寻找一个更有效的方法来做到这一点,因为它在节点服务器上运行,也是一个更聪明的方式(不必更高效)。

注意:我正在使用节点v7.8.0,因此可以使用ES6。

更新:

传播运算符比应用慢得多

所以我的代码是这样快得多:

 return first.map((item, i) => [].concat.apply(item, index(i, clone) )); 

JSPERF:

我testing了这个jsperf中的所有答案, @ ibrahimMahrir的方式显然是最快的。

 /** * Will return all the values at ${index} of each array in ${arrays} * Example: index(1, [[1,2], [3,4]]); //[2, 4] */ function index(index, arrays){ let results = []; for(let i = 0, len = arrays.length; i < len; i++) results.push(arrays[i][index]); return results; } let arrays = [ //1 [[1, 2], [3, 4], [5, 6]], //2 [[10, 20], [30, 40], [50, 60]], //3 [[100, 200], [300, 400], [500, 600]], //N [[10000, 20000], [30000, 40000], [50000, 60000]], ]; let first = arrays.shift(); let output = first.map((item, i) => item.concat( ...index(i, arrays) )); console.log(output); 

使用reduce和其姐妹是在性能成本。 使用基本的for循环不是最漂亮的,但肯定会更快。

 function group(arrays){ let results = [], len = arrays.length; if(!len) return results; // if this line is not necessary then remove it let i, j, k, innerLen = arrays[0].length; for(j = 0; j < innerLen; j++) { let arr = []; for(i = 0; i < len; i++) for(k = 0; k < arrays[i][j].length; k++) // assuming the last level of arrays could be of different lengths arr.push(arrays[i][j][k]); results.push(arr); } return results; } let arrays = [[[1,2],[3,4],[5,6]],[[10,20],[30,40],[50,60]],[[100,200],[300,400],[500,600]],[[10000,20000],[30000,40000],[50000,60000]]]; console.log(group(arrays)); 

这是一个典型的缩放工作与映射。 你可以这样做:

 var arrs = [[[1, 2], [3, 4], [5, 6]], [[10, 20], [30, 40], [50, 60]], [[100, 200], [300, 400], [500, 600]], [[10000, 20000], [30000, 40000], [50000, 60000]]], res = arrs.reduce((p,c) => p.map((s,i) => s.concat(c[i]))); console.log(res); 

这里是我尝试一个可读的方法,基于使用zipflatten实用程序方法分解操作:

 let arrays = [ //1 [[1, 2], [3, 4], [5, 6]], //2 [[10, 20], [30, 40], [50, 60]], //3 [[100, 200], [300, 400], [500, 600]], //N [[10000, 20000], [30000, 40000], [50000, 60000]], ] // from http://stackoverflow.com/a/10284006/7256039 const zip = a => a[0].map((_,i) => a.map(e => e[i])) const flatten = a => [].concat(...a) let result = zip(arrays).map(flatten) console.log(result) 
 .as-console-wrapper { min-height: 100%; }