我有一个如下所示的数组:
var array = [ [1,3,9],
[4,6,8],
[3,7,5],
[2,8,4] ];
我想获得每列的平均数,但是现在我只是想总结它们。这是我的代码:
var sum = function(arr) {
return arr.reduce(function(a, b) { return a + b; }, 0);
};
var tests = array.map(function(v, i) {
return sum(array.map(function(v) { return v[i]; }))
});
return tests;
输出正确地转换总和,但它似乎与行(4行)一样多,而不是3对应于列。这是输出:
tests = [10, 24, 26, NULL]
知道为什么会这样吗?如何仅针对行而不是行执行计算?
修改
我使用Nenad的答案给出了正确的结果。但是我需要在Google表格的脚本编辑器上实现它,它似乎无法通过" =>"来理解缩短的功能。我更换了较长版本的缩短件,但我得不到相同的结果。
var array = [ [1,3,9],
[4,6,8],
[3,7,5],
[2,8,4] ];
var sums = array.reduce(function(r, e, i) {
e.forEach(function(a,j) { r[j] = (r[j] || 0) + a;
if (i == array.length-1) { r = r.map(function(el){ return el/array.length; }); }
});
return r;
}, [])
console.log(sums);

我没有看到这个和缩短版本之间的任何区别,但是这个版本会返回:
sums = [0.15625, 0.75, 1.34375];
而不是:
sums = [2.5, 6, 6.5];
总和正确完成,但是当我划分" el / array.length"甚至" el / 4",结果是这3个奇怪的数字。我不明白那些人来自哪里。我哪里出错了?
答案 0 :(得分:2)
您可以使用reduce()
和forEach()
返回结果。
var array = [
[1, 3, 9],
[4, 6, 8],
[3, 7, 5],
[2, 8, 4]
];
var sums = array.reduce(function(r, e, i) {
e.forEach((a, j) => r[j] = (r[j] || 0) + a)
return r;
}, [])
console.log(sums)
要计算每列的平均值,您可以在最后一次迭代的数组中添加map()
。
var array = [
[1, 3, 9],
[4, 6, 8],
[3, 7, 5],
[2, 8, 4]
];
var sums = array.reduce(function(r, e, i) {
e.forEach((a, j) => r[j] = (r[j] || 0) + a)
if (i == array.length - 1) r = r.map(el => el / array.length);
return r;
}, [])
console.log(sums)
答案 1 :(得分:1)
要获得每列的平均值,您首先必须知道列数。然后使用map()
获取每个列,并使用reduce()
现在我们有了列,总和然后除以列长度。
const arrayColumn = (a, n) => a.map(x => x[n]);
const arraySum = (a) => a.reduce((b,c) => b + c);
var arr = [
[1,3,9],
[4,6,8],
[3,7,5],
[2,8,4]
];
for(i=0; i<arr[0].length; i++){
console.log(arraySum((col = arrayColumn(arr, i))) / col.length);
}
&#13;
答案 2 :(得分:1)
这会将2d行数组转换为2d列数组,然后将每个内部列数组映射到平均值。有一些样板文件可以使内部减少不可变,你可以使用lodash / fp或其他库来清理它。
const array = [
[1,3,9],
[4,6,8],
[3,7,5],
[2,8,4]
];
const averageColumns = array => array.reduce((acc, row) => {
return row.reduce((accRow, col, index) => {
const cols = accRow[index] || [];
return [...accRow.slice(0, index), cols.concat(col), ...accRow.slice(index + 1)];
}, acc);
}, []).map(avg);
const avg = array => array.reduce((acc, next) => acc + next, 0) / array.length;
console.log(averageColumns(array));
&#13;
答案 3 :(得分:0)
map()
+ reduce()
解决方案
var array = [ [1,3,9], [4,6,8], [3,7,5], [2,8,4] ];
array.map(function(item, i, arr) {
arr[i] = item.reduce((a, b) => a + b, 0) / 2;
console.log(arr[i])
});
&#13;
我稍微修改了你的代码
你错了return sum(array.map(function(v) { return v[i]; }))
var array = [ [1,3,9],
[4,6,8],
[3,7,5],
[2,8,4] ];
function sum(arr) {
return arr.reduce(function(a, b) { return a + b; }, 0);
};
var tests = array.map(function(v, i, arr) {
return sum(arr[i])
});
tests;
答案 4 :(得分:0)
您可以转置数组数组,
流行的实用程序库(ramda for ex)有一个转置实现,
但实现自己很容易:
const trans = arr => arr[0].map((_,i) => arr.map(x => x[i]))
var array = [
[1,3,9],
[4,6,8],
[3,7,5],
[2,8,4]
];
const res = trans(array)
console.log(res)
// to get the sum you can use reduce
console.log(res.map( x => x.reduce((a,b) => a + b )))
&#13;
答案 5 :(得分:0)
我会这样做;
var array = [ [1,3,9],
[4,6,8],
[3,7,5],
[2,8,4] ];
result = array.map(a => a.reduce((p,c,_,a) => p + c/a.length,0));
console.log(result);
根据评论......是的,他们是正确的,正确的解决方案应该是通过.map()
和.reduce()
的转换;
var array = [ [1,3,9],
[4,6,8],
[3,7,5],
[2,8,4] ],
result = array.reduce((p,c) => p.map((n,i) => n + c[i]/array.length), Array(array[0].length).fill(0));
console.log(result);