array.map()

时间:2017-01-15 22:29:45

标签: javascript arrays multidimensional-array google-sheets

我有一个如下所示的数组:

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个奇怪的数字。我不明白那些人来自哪里。我哪里出错了?

6 个答案:

答案 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;
&#13;
&#13;

答案 2 :(得分:1)

这会将2d行数组转换为2d列数组,然后将每个内部列数组映射到平均值。有一些样板文件可以使内部减少不可变,你可以使用lodash / fp或其他库来清理它。

&#13;
&#13;
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;
&#13;
&#13;

答案 3 :(得分:0)

map() + reduce()解决方案

&#13;
&#13;
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;
&#13;
&#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)有一个转置实现,
但实现自己很容易:

&#13;
&#13;
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;
&#13;
&#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);