Суммирование записей и консолидация на основе идентификаторов в массиве - PullRequest
3 голосов
/ 05 марта 2020

У меня есть массив записей, которые содержат объекты, каждая с id и amount. Теперь в этом массиве некоторые элементы имеют одинаковый идентификатор. Что мне нужно сделать, так это перебрать этот массив и, во-первых, суммировать значения для записей с одинаковым идентификатором, а затем вернуть только одну запись в этом случае - поэтому я получаю массив с только уникальными идентификаторами - - каждый из них также содержит свойство amount.

Другими словами, я хочу взять этот массив:

const records = [
  {id: 1, amount: 10},
  {id: 1, amount: 20},
  {id: 2, amount: 10},
  {id: 3, amount: 10},
  {id: 3, amount: -10}
];

... и создать этот массив:

const transformedRecords = [
  {id: 1, amount: 30},
  {id: 2, amount: 10},
  {id: 3, amount: 0}
];

Я думал об использовании for-of l oop для этого, но это может быть довольно многословным, и я предполагаю, что есть более краткий способ сделать это sh - возможно, с помощью reduce() ? Какой элегантный способ подойти к этому, предпочтительно с использованием синтаксиса es6 +?

Ответы [ 2 ]

2 голосов
/ 05 марта 2020

Используйте Array.reduce, для каждой итерации проверяйте, есть ли у вас объект с текущим id в accumulator, если да, добавьте amounts, если нет, pu sh текущий объект к accumulator:

const records = [
  {id: 1, amount: 10},
  {id: 1, amount: 20},
  {id: 2, amount: 10},
  {id: 3, amount: 10},
  {id: 3, amount: -10},
  {id: 4, amount: -10},
  {id: 4, amount: -10}
];

const result = records.reduce((acc, curr) => {
  const ndx = acc.findIndex(e => e.id === curr.id);

  if(ndx > -1) {
    acc[ndx].amount += curr.amount
  }
  else{
    acc.push(curr)
  }

  return acc;
}, [])

console.log(result)
2 голосов
/ 05 марта 2020

Вы можете использовать reduce() для создания объекта, а затем использовать map() для его записей, чтобы создать массив объектов назад

const records = [
  {id: 1, amount: 10},
  {id: 1, amount: 20},
  {id: 2, amount: 10},
  {id: 3, amount: 10},
  {id: 3, amount: -10}
];
const res = Object.entries(records.reduce((ac, a) => {
  ac[a.id] = (a[a.id] || 0) + a.amount;
  return ac
}, {})).map(([id, amount]) => ({id, amount: amount < 0 ? 0 : amount}))

console.log(res)
...