Javascript ES6计算对象数组的总和

时间:2019-07-22 19:08:40

标签: javascript arrays ecmascript-6

我有多个对象数组,这些对象具有字符串属性html += "<div>"; html += "<table>"; // HTML table starts here //Rows are generated using myData 2-D array already defined myData.forEach(function(value){ html += "<tr>"; //mykeys are keys for all the row values already defined for(mykeys in value){ html += "<td>" //on Click event is attached with all the row entries or table values html+= "<a onClick=\"(e)=> \"compareMe(e,key,value[mykeys])\">" html += "<span>" +value[mykeys] +"</span>" html += "</a>" html += "</td>" } html += "</tr>"; }); html += "</table>"; html += "</div>"; // This function is called on generating on Click event on the output values function compareMe(value){ if(value==="2"){ html += "<td>" +"X" +"</td>"; document.getElementById("message").innerHTML += html; return html; } } 和数字属性"CountType"

必须通过"ItemCount"属性将这些对象加起来以计算所有项的总数。

例如,我需要知道卷,图纸,照片等的总数。

尝试#1:我尝试的这段代码返回0。可能是因为我需要循环遍历外部数组以对嵌套数组进行比较。

"CountType"

输入

项目数

function sumByProperty(items, prop) {
  if (items == null) {
      return 0;
  }
  return items.reduce(function (a, b) {
      return b[prop] == null ? a : a + b[prop];
  }, 0);
}

期望的输出

总数

[
    [
      {"CountType":"Volumes","ItemCount":3},
      {"CountType":"Sheets","ItemCount":6},
      {"CountType":"Photos","ItemCount":3},
      {"CountType":"Boxes","ItemCount":1},
      {"CountType":"Other","ItemCount":2}
    ],
    [
      {"CountType":"Volumes","ItemCount":1},
      {"CountType":"Sheets","ItemCount":1},
      {"CountType":"Photos","ItemCount":3},
      {"CountType":"Boxes","ItemCount":0},
      {"CountType":"Other","ItemCount":1}
    ],
    [
      {"CountType":"Volumes","ItemCount":1},
      {"CountType":"Sheets","ItemCount":0},
      {"CountType":"Photos","ItemCount":3},
      {"CountType":"Boxes","ItemCount":4},
      {"CountType":"Other","ItemCount":5}
    ]
]

更新:这是我尝试运行该函数的方式:

https://jsfiddle.net/yd051o76/2/

3 个答案:

答案 0 :(得分:4)

  

可能是因为我需要遍历外部数组才能对嵌套数组进行比较。

实际上,您可以将数组展平:

 function sumByProperty(items, prop) {
   return items.flat().reduce(function (a, b) {
     return b[prop] == null ? a : a + b[prop];
   }, 0);
 }

 const result = [
   { CountType: "Volumes", ItemCount: sumByProperty(input, "Volumes"), },
   //...
 ];

但是我宁愿使用哈希表进行动态分组,这样您只需要迭代一次就可以了,而无需命名所有属性:

  const hash = new Map();

   for(const { CountType, ItemCount } of input.flat())
      hash.set(CountType, (hash.get(CountType) || 0) + ItemCount);

  const result = [...hash.entries()].map(([CountType, ItemCount]) => ({ CountType, ItemCount }));

答案 1 :(得分:1)

下面是一个示例,该示例使用2个reduce函数和一个for ... in ...将结果合并回父reducer。

诀窍是确保将累加器初始化为null,以便可以定义自己的累加器。然后,只需要减少数组的数组并让另一个reducer运行对象数组即可。完成后,您只需要将内部数组的结果合并回父级即可。 (可能是做这部分的更好方法)

提琴:https://jsfiddle.net/mswilson4040/jcp9x6ba/26/

const json = [
  [
    {"CountType":"Volumes","ItemCount":3},
    {"CountType":"Sheets","ItemCount":6},
    {"CountType":"Photos","ItemCount":3},
    {"CountType":"Boxes","ItemCount":1},
    {"CountType":"Other","ItemCount":2}
  ],
  [
    {"CountType":"Volumes","ItemCount":1},
    {"CountType":"Sheets","ItemCount":1},
    {"CountType":"Photos","ItemCount":3},
    {"CountType":"Boxes","ItemCount":0},
    {"CountType":"Other","ItemCount":1}
  ],
  [
    {"CountType":"Volumes","ItemCount":1},
    {"CountType":"Sheets","ItemCount":0},
    {"CountType":"Photos","ItemCount":3},
    {"CountType":"Boxes","ItemCount":4},
    {"CountType":"Other","ItemCount":5}
  ]
];

const counts = json.reduce( (acc, currentArray) => {
	acc = acc ? acc : {};
  const arrCounts = currentArray.reduce( (_acc, _item) => {
  	_acc = _acc ? _acc : {};
    _acc[_item.CountType] = _acc[_item.CountType] ? _acc[_item.CountType] + _item.ItemCount : _item.ItemCount;
    return _acc;
  }, null);
  for (const item in arrCounts) {
  	acc[item] = acc[item] ? acc[item] + arrCounts[item] : arrCounts[item];
  }
  return acc;
}, null);


console.log(counts);

答案 2 :(得分:0)

尝试(输入数据,h = {},r为结果);

data.map(a=> a.map(x=> h[x.CountType]=x.ItemCount+(h[x.CountType]||0) ))

r= Object.keys(h).map(k=> ({CountType:k, ItemCount:h[k] }) );

let data = [[
  {"CountType":"Volumes","ItemCount":3},
  {"CountType":"Sheets","ItemCount":6},
  {"CountType":"Photos","ItemCount":3},
  {"CountType":"Boxes","ItemCount":1},
  {"CountType":"Other","ItemCount":2}
],
[
  {"CountType":"Volumes","ItemCount":1},
  {"CountType":"Sheets","ItemCount":1},
  {"CountType":"Photos","ItemCount":3},
  {"CountType":"Boxes","ItemCount":0},
  {"CountType":"Other","ItemCount":1}
],
[
  {"CountType":"Volumes","ItemCount":1},
  {"CountType":"Sheets","ItemCount":0},
  {"CountType":"Photos","ItemCount":3},
  {"CountType":"Boxes","ItemCount":4},
  {"CountType":"Other","ItemCount":5}
]];

let r,h = {};
data.map(a=> a.map(x=> h[x.CountType]=x.ItemCount+(h[x.CountType]||0) ))
r= Object.keys(h).map(k=> ({CountType:k, ItemCount:h[k] }) );

console.log(r);