垂直高效/优雅地排列数组(矩阵)数组

Joh*_*ohn 5 javascript arrays functional-programming data-structures

在Javascript中,如果我有一个表示矩阵的数组数组,比如说

x = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12]
];
Run Code Online (Sandbox Code Playgroud)

将它"水平"相加很容易就可以完成

x.map(function(y){
    return y.reduce(function(a,b){
        return a+b;
    });
});
Run Code Online (Sandbox Code Playgroud)

现在我想计算"垂直"总和,这可以做到

x.reduce(function(a, b){
    return a.map(function(v,i){
        return v+b[i];
    });
});
Run Code Online (Sandbox Code Playgroud)

但我对这个版本不满意,我希望有更好,更优雅,更直接的东西.也许预先转换矩阵的简单方法?任何人?

请注意,几天前我问了一个类似的问题(链接)但是缺乏更大的图景.

Nin*_*olz 13

您可以对同一索引处的值求和.

使用: array.reduce(sum)

var sum = (r, a) => r.map((b, i) => a[i] + b);

console.log([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]].reduce(sum));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)


dtb*_*ess 6

arrayOfArrays = [
  [1,2,3,4],
  [5,6,7,8],
  [9,10,11,12]
];

arrayOfArrays.reduce(function(array1, array2) {
  return array1.map(function(value, index) {
    return value + array2[index];
  });
});
Run Code Online (Sandbox Code Playgroud)

为了我自己的利益,也希望其他人的利益,我想解释一下嵌套reduce/ map方法如何执行等长数组的垂直求和。这是OP提供的完全可接受的版本。

reduce方法对一个累加器应用一个函数,并从左到右对数组的每个值应用以将其减少为单个值(MDN)。

在此示例的情况下,在第一次迭代中,将前两个数组传递给reduceas array1和的回调函数array2。回调函数的返回值是map应用于array1 的方法的结果。

map返回一个新数组,并在该数组的每个元素上调用提供的函数。(MDN)。

因此,map迭代每个值array1并将其添加到array2同一索引位置的值中。这些结果被推到一个新的数组,然后返回到该reduce方法。

现在,刚刚返回的总和数组成为new,array1reduce调用其函数,并传入new array1和下一个array作为new array2

重复此过程,直到我们用完数组 arrayOfArrays

从...开始:

arrayOfArrays = [
  [1,2,3,4],
  [5,6,7,8],
  [9,10,11,12]
];
Run Code Online (Sandbox Code Playgroud)

reduce遍历的第一次迭代:

array1 [1,2,3,4]
array2 [5,6,7,8]
Run Code Online (Sandbox Code Playgroud)

到的回调函数reduce。的返回值reduce 是一个新数组,通过使用map来将的每个值array1加到array2同一位置的值上而得出:

array1 [1,2,3,4]
array2 [5,6,7,8]
return [6,8,10,12]
Run Code Online (Sandbox Code Playgroud)

此值返回到reduce方法,并成为新值 array1array1然后将下一个数组(array2)再次传递给 reduce回调函数,并通过map方法求和:

array1 [6,8,10,12]
array2 [9,10,11,12]
return [15,18,21,24]   // returned by map()
Run Code Online (Sandbox Code Playgroud)


Ber*_*rgi 1

我认为您对没有本机zip函数感到不满,因为这就是您的reduceinmap本质上所做的事情。您要么必须自己实现它,要么从Ramda这样的库导入它,以便编写如下优雅的代码:

var verticalSum = x.map(R.zipWith(function(a,b){ return a+b; }));
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找有效的解决方案,基本上没有比显式循环更好的方法了。