键值对匹配的嵌套对象中的值求和

时间:2020-08-28 21:26:41

标签: javascript arrays object

当值在对象中时,我试图对它们求和。

给出以下数组:

const data = [
  {
    id: "tom",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "tom",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "dick",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
];

我需要对ID匹配的values对象中的每个数字求和, 给出以下结果:

const result = [
  {
    id: "tom",
    values: { ten: 20, twenty: 40, thirty: 60 },
  },
  {
    id: "dick",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 20, twenty: 40, thirty: 60 },
  }
];

有没有简单的方法来实现这一目标?

也许是reduce和map的某种组合?

2 个答案:

答案 0 :(得分:3)

使用Array#reduce累积所需的数据。为此,遍历对象并查看在新的累积对象(开始时为空)中,结果对象是否存在具有此ID的属性。如果没有,请创建一个并在其中添加对象。否则,将值对象的每个属性的值添加到对象中。

最后使用Object#values从对象中获取所需的数组。

const data = [
  {
    id: "tom",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "tom",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "dick",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
];

let res = Object.values(data.reduce((acc, cur) => {
    if (!acc.hasOwnProperty(cur.id)) {
        acc[cur.id] = { id: cur.id, values: cur.values};
    } else {
        Object.entries(cur.values).forEach(([key,value]) => acc[cur.id].values[key] += value);
    }
    return acc;
}, {}));

console.log(res);

答案 1 :(得分:0)

或者是老式但简单的循环样式

const data = [
  {
    id: "tom",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "tom",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "dick",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
  {
    id: "harry",
    values: { ten: 10, twenty: 20, thirty: 30 },
  },
];

// New data
const newData = [];

// Loop
for(let i = 0; i < data.length; i++) {
  const item = data[i];
  let push = true;
  for(let i = 0; i < newData.length; i++) if(item.id === newData[i].id) {
    push = false;
    for(const key in newData[i].values) newData[i].values[key] += item.values[key];
  }
  if(push) newData.push(item);
}

// Log
console.log(newData)