如何对数据项进行分组,并通过求和相关值来合并其属性?

问题描述 投票:0回答:2

Given 是一个数据项数组,其中需要对每个属性的值进行求和,其中其键与附加提供的属性名称(用作分组键)不同。

因此,对于分组键

name
和样本数据,如 ...

[{
  name: "Name1",
  amt: 100,
  tax: 10,
  total: 110,
}, {
  name: "Name2",
  amt: 50,
  tax: 5,
  total: 55,
}, {
  name: "Name1",
  amt: 70,
  tax: 7,
  total: 77,
}]

...预期结果是...

[{
  name: "Name1",
  amt: 170,
  tax: 17,
  total: 187,
}, {
  name: "Name2",
  amt: 50,
  tax: 5,
  total: 55,
}]

有没有一种方法或参考可以产生像上面这样的输出?

javascript arrays data-structures merge reduce
2个回答
-1
投票

使用

Array::reduce()
构造一个新数组,通过映射中的名称记住项目并将其放入结果数组中,并使用映射以新总计更新项目:

const result = arr.reduce((r, {name, ...item}) => {
  const found = r.map.get(name);
  if(found){
    Object.keys(item).forEach(key => found[key] += item[key]);
  } else {
    r.map.set(name, r.arr[r.arr.length] = {name, ...item});  
  }
  return r;
}, {arr: [], map: new Map}).arr;

console.log(result);
<script>
const arr = [
{
  name: "Name1",
  amt : 100,
  tax : 10,
  total : 110
},
{
  name: "Name2",
  amt : 50,
  tax : 5,
  total : 55
},
{
  name: "Name1",
  amt : 70,
  tax : 7,
  total : 77
}
]
</script>


-2
投票

您可以通过键值将每个对象缩减为映射。对于每个项目,循环遍历键并忽略

key
参数。

将传入的

item[k]
求和到
existing[k]
条目上。

最后,返回

values()
Map
并将迭代器展开到新的
Array
对象中。

const reduceBy = (data, key) =>
  [...data.reduce((map, item) => {
    const existing = map.get(item[key]) ?? { [key]: item[key] };
    for (let k in item) {
      if (k !== key) {
        existing[k] = (existing[k] ?? 0) + item[k];
      }
    }
    return map.set(item[key], existing);
  }, new Map).values()];

const
  input = [
    { name: "Name1", amt: 100, tax: 10, total: 110 },
    { name: "Name2", amt:  50, tax:  5, total:  55 },
    { name: "Name1", amt:  70, tax:  7, total:  77 }
  ],
  expected = [
    { name: "Name1", amt: 170, tax: 17, total: 187 },
    { name: "Name2", amt:  50, tax:  5, total:  55 }
  ],
  actual = reduceBy(input, 'name');

console.log(JSON.stringify(actual) === JSON.stringify(expected));
.as-console-wrapper { top: 0; max-height: 100% !important; }

© www.soinside.com 2019 - 2024. All rights reserved.