JavaScript 对多维数组元素值求和

JavaScript sum multidimensional array element values

本文关键字:求和 数组元素 JavaScript      更新时间:2023-09-26

我有以下数组,我需要计算每组值的总和。我可以在数组的 dataArr[1] 处获取每个组的第一个值的总和,但我还需要为数组中的每个组获取 dataArr[2] 处第二个值的总和。

var dataArr = [    [
    "Group One",
    1,
    1
],
[
    "Group Four",
    0,
    1
],
[
    "Group Three",
    0,
    1
],
[
    "Group Three",
    1,
    0
],
[
    "Group Four",
    0,
    1
],
[
    "Group Two",
    2,
    1
],
[
    "Group Four",
    1,
    0
],
[
    "Group Three",
    0,
    1
],
[
    "Group Three",
    0,
    1
],
[
    "Group One",
    1,
    0
],
[
    "Group Three",
    0,
    1
],
[
    "Group Two",
    1,
    0
]
];

如何计算第二个值的总和并生成如下所示的多维数组:

[["Group One", 2, 1], ["Group Four", 1, 2], ["Group Three", 1, 4], ["Group Two", 3, 1]]

以下是我的代码,灵感来自这里:

var result = [];
$(dataArr).each(function() {
    var key = this[0];
    var value = this[1];
    if (result[key]) {
        result[key] += value;       
    } else {
        result[key] = value;
    }
});

此提案使用临时对象来引用结果数组。

var dataArr = [["Group One", 1, 1], ["Group Four", 0, 1], ["Group Three", 0, 1], ["Group Three", 1, 0], ["Group Four", 0, 1], ["Group Two", 2, 1], ["Group Four", 1, 0], ["Group Three", 0, 1], ["Group Three", 0, 1], ["Group One", 1, 0], ["Group Three", 0, 1], ["Group Two", 1, 0]],
    result = function (data) {
        var r = [], o = {};
        data.forEach(function (a) {
            if (!o[a[0]]) {
                o[a[0]] = [a[0], 0, 0];
                r.push(o[a[0]]);
            }
            o[a[0]][1] += a[1];
            o[a[0]][2] += a[2];
        });
        return r;
    }(dataArr);
    
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

具有Array.forEachObject.keysArray.map方法的解决方案:

var keys_obj = {}, key;
dataArr.forEach(function(v){
    key = v[0];
    if (! (key in keys_obj) ) {
        keys_obj[key] = [v[1], v[2]];
    } else {
        keys_obj[key][0] += v[1];
        keys_obj[key][1] += v[2];
    }
});
var result = [];
result = Object.keys(keys_obj).map(function(v){
    return [v, keys_obj[v][0], keys_obj[v][1]];
});
console.log(result);
// the output: 
[["Group Four", 1, 2], ["Group Three", 1, 4], ["Group One", 2, 1], ["Group Two", 3, 1]]

使用 map 和 reduce 方法:

var reduced = dataArr.reduce(function(obj,item) {
  if(obj.hasOwnProperty(item[0])) {
    obj[item[0]][0] += item[1]
    obj[item[0]][1] += item[2]
  } else {
    obj[item[0]] = []
    obj[item[0]][0] = item[1]
    obj[item[0]][1] = item[2]
  }
  return obj;
}, {});
var grouped = Object.keys(reduced).map(function(item) {
  return [item, reduced [item][0], reduced [item][1]]
});
  1. 使用对象而不是数组来跟踪自定义属性。
  2. 不要每个键
  3. 使用单个值,而是使用每个键的数组。现在,您可以为每个对象支持 1、2 或 47 个值。
  4. 如果你将来有超过 2 个值,我建议使用 for 循环来一般地处理它们。

var dataArr = [["Group One",1,1],["Group Four",0,1],["Group Three",0,1],
               ["Group Three",1,0],["Group Four",0,1],["Group Two",2,1],
               ["Group Four",1,0],["Group Three",0,1],["Group Three",0,1],
               ["Group One",1,0],["Group Three",0,1],["Group Two",1,0]];
var sumByKey = {};
dataArr.forEach(function(item){
  var key = item[0];
  if (!sumByKey[key]) sumByKey[key] = [];
  for (var i=0;i<2;++i){
    sumByKey[key][i] = (sumByKey[key][i] || 0) + item[i+1];
  }
});
var output = neatJSON(sumByKey,{wrap:30,short:true,aligned:true});
document.querySelector('pre').innerHTML = output;
<script src="http://phrogz.net/JS/neatjson/neatjson.js"></script>
<pre></pre>

使用对象和Array.prototype.forEach()方法

var o = {};
dataArr.forEach(function(e) {
    var t = o[e[0]];
    if (t) {
        t.first += e[1];
        t.second += e[2];
    } else {
        t = {};
        t.first = e[1];
        t.second = e[2];
        o[e[0]] = t;
    }
});

用法:

console.log(o["Group Four"].first); // first sum for "Group Four"
console.log(o["Group Four"].second); // second sum for "Group Four"
console.log(o); // all groups with their sums

通过使用Map对象以及reducemap函数来解决这个古老(看似常见)问题的另一种方法。

const dataArr = [
  ['Group One', 1, 1],
  ['Group Four', 0, 1],
  ['Group Three', 0, 1],
  ['Group Three', 1, 0],
  ['Group Four', 0, 1],
  ['Group Two', 2, 1],
  ['Group Four', 1, 0],
  ['Group Three', 0, 1],
  ['Group Three', 0, 1],
  ['Group One', 1, 0],
  ['Group Three', 0, 1],
  ['Group Two', 1, 0],
];
const sumArray = (data) =>
  Array.from(
    data.reduce((accum, item) => {
      let prev = accum.get(item[0]) || [0, 0];
      accum.set(item[0], [prev[0] + item[1], prev[1] + item[2]]);
      return accum;
    }, new Map())
  ).map((entry) => [entry[0], entry[1][0], entry[1][1]]);
console.log(sumArray(dataArr));

Map实例用作reduce中的累加器,它存储每个"组"的总和的"元组",然后将其转换为数组并映射(没有双关语)以将其展平为与原始数据相同的[[string, number, number]]形状。