如何对对象数组中相同字段的值求和?

时间:2019-10-29 19:07:03

标签: javascript arrays

我有一个对象数组

const data = [
  { category: 'shopping', amount: 50 }, 
  { category: 'rent', amount: 1000 }, 
  { category: 'groceries', amount: 20 }, 
  { category: 'shopping', amount: 50 }
]

我正在尝试总结每个类别的金额

const result = [
  { category: 'shopping', amount: 100 },
  { category: 'rent', amount: 1000 },
  { category: 'groceries', amount: 20 }
]

到目前为止,我正在考虑删除类别的“重复项”并将其存储到数组中

const temp = data.map((obj) => {
  return obj.category
})

const categories = [...new Set(temp)] // ['shopping','rent','groceries']

使用上述方法,我正在考虑进行嵌套循环,但是经过多次尝试,我失败了。

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

您可以使用reduce()来做到这一点。

根据给定的数据进行迭代,如果存在与当前项目相同的category项,则添加amount,否则将当前项添加为新条目。

const data = [
  { category: 'shopping', amount: 50 }, 
  { category: 'rent', amount: 1000 }, 
  { category: 'groceries', amount: 20 }, 
  { category: 'shopping', amount: 50 }
];

let result = data.reduce((acc, curr) => {
  let item = acc.find(item => item.category === curr.category);

  if (item) {
    item.amount += curr.amount;
  } else {
    acc.push(curr);
  }

  return acc;
}, []);

console.log(result);

这里是使用对象作为累加器的另一种方法。这具有性能上的优势,因为我们不必在每次迭代时都调用find()。归功于frodo2975的建议。

const data = [
  { category: 'shopping', amount: 50 }, 
  { category: 'rent', amount: 1000 }, 
  { category: 'groceries', amount: 20 }, 
  { category: 'shopping', amount: 50 }
];

let result = Object.values(data.reduce((acc, curr) => {
  let item = acc[curr.category];

  if (item) {
    item.amount += curr.amount;
  } else {
    acc[curr.category] = curr;
  }

  return acc;
}, {}));

console.log(result);

答案 1 :(得分:1)

我将专注于有效地计算每个类别的总数,然后以所需的格式重组数据。像这样:

// Construct an object mapping category to total amount.
const totals = data.reduce((totals, { category, amount }) => {
    totals[category] = (totals[category] || 0) + amount;
}, {});

// Format the data as you like.
const result = Object.entries(totals).map(([category, amount]) => ({ category, amount });

答案 2 :(得分:1)

使用reduce方法的另一个版本:)

const data = [
  { category: 'shopping', amount: 50 },
  { category: 'rent', amount: 1000 },
  { category: 'groceries', amount: 20 },
  { category: 'shopping', amount: 50 }
];

const result = data.reduce((a,c) => {
  a[c.category] = a[c.category] || {category: c.category, amount: 0};
  a[c.category].amount += c.amount;
  return a;
}, {})

console.log(Object.values(result));