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

时间:2015-08-21 11:59:39

标签: javascript arrays data-structures functional-programming

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

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

横向总结""很简单,可以像

一样完成
x.map(function(y){
    return y.reduce(function(a,b){
        return a+b;
    });
});

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

x.reduce(function(a, b){
    return a.map(function(v,i){
        return v+b[i];
    });
});

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

请注意,几天前我问了一个类似的问题(link)但是缺乏更大的影响。

6 个答案:

答案 0 :(得分:12)

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

使用: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));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:5)

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

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

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

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

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

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

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

重复这一过程,直到我们用完arrayOfArrays

中的数组

从:

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

reduce pass的第一次迭代:

array1 [1,2,3,4]
array2 [5,6,7,8]

reduce的回调函数。 reduce的返回值 是使用map添加array1的每个值而派生的新数组 array2在同一位置的值:

array1 [1,2,3,4]
array2 [5,6,7,8]
return [6,8,10,12]

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

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

答案 2 :(得分:2)

我认为你不满意没有原生zip功能,因为这是你reducemap基本上正在做的事情。您要么自己实现它,要么从像Ramda这样的库中导入它,以便编写如下优雅的代码:

var verticalSum = x.map(R.zipWith(function(a,b){ return a+b; }));

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

答案 3 :(得分:1)

非常优雅,仅适用于我的方阵。

   x = [[1,2,3,4],
        [5,6,7,8],
        [9,10,11,12]
    ];
    var sum = function(arr) {
      return arr.reduce(function(a, b){ return a + b; }, 0);
    };

    x.map(function(row, i) {
      return sum(x.map(function(row) { return row[i]; }));
    });

http://jsfiddle.net/btux9s2d/控制台日志示例。

任何大小的矩阵,不是那么优雅,但也许会帮助你的方式: http://jsfiddle.net/btux9s2d/2/

答案 4 :(得分:0)

通过此功能,您可以使用递归性对任何维数的数组求和:

function sumRecursiveArray(arr) {
  return arr.reduce(function(acc, value) {
    return acc + (Array.isArray(value) ? sumRecursiveArray(value) : value);
  }, 0);
}

var sum = sumRecursiveArray([[1,1,1],[2,2,2]]);
console.log(sum); // 9

答案 5 :(得分:0)

total