Используйте сокращение для суммирования значений в массиве объектов - PullRequest
1 голос
/ 14 июля 2020

У меня есть этот массив объектов:

const data = [
  {val: 40, color: 'red'},
  {val: 5, color: 'green'},
  {val: 55, color: 'lime'}
]

Это то, что я хотел бы получить:

const result = [
  {val: 40, color: 'red'},
  {val: 45, color: 'green'},
  {val: 100, color: 'lime'}
]

Итак, каждый элемент должен иметь одинаковый цвет и совокупное значение предыдущие данные.

Вот что я пробую:

const data = [
  {val: 40, color: 'red'},
  {val: 5, color: 'green'},
  {val: 55, color: 'lime'}
]

// const result = [
//   {val: 40, color: 'red'},
//   {val: 45, color: 'green'},
//   {val: 100, color: 'lime'}
// ]

const result = data.reduce((r, value, i) => {
    const { val, color } = value
    const cumVal = i === 0 ? val : r[i - 1].val
    const newDatum = { val: cumVal, color }
    return newDatum
}, data[0])

console.log(result)

Где ошибка? Почему r[i - 1] не определено?

Ответы [ 3 ]

4 голосов
/ 14 июля 2020

В вашем коде было четыре проблемы:

  • В этой строке const cumVal = i === 0 ? val : r[i - 1].val вы должны назначить 0 как значение по умолчанию, а не val
  • В этой строке const newDatum = { val: cumVal, color } вам нужно добавить val к cumVal
  • В качестве начального значения вы должны передать пустой массив, а не первый элемент вашего data массива, потому что вы хотите иметь массив в результате, а не объект
  • Вам нужно возвращать r на каждой итерации, а не newDatum - опять же, вы хотите, чтобы в конце был массив, а не объект

Вот фиксированная версия:

const data = [
  {val: 40, color: 'red'},
  {val: 5, color: 'green'},
  {val: 55, color: 'lime'}
]

// const result = [
//   {val: 40, color: 'red'},
//   {val: 45, color: 'green'},
//   {val: 100, color: 'lime'}
// ]

const result = data.reduce((r, value, i) => {
    const { val, color } = value
    const cumVal = i === 0 ? 0 : r[i - 1].val
    const newDatum = { val: val + cumVal, color }
    r.push(newDatum);
    return r;
}, [])

console.log(result)
4 голосов
/ 14 июля 2020

Вы начинаете сокращение с одного элемента, который не является массивом.

Вместо этого вы можете закрыть sum и сопоставить новые объекты.

const
    data = [{ val: 40, color: 'red' }, { val: 5, color: 'green' }, { val: 55, color: 'lime' }],
    result = data.map(
        (sum => ({ val, color }) => ({ val: sum += val, color }))
        (0)
    );

console.log(result);
0 голосов
/ 14 июля 2020
const result2 = data.reduce((acc, { val, color }, i) => {
    val += (i>0) ? acc[i - 1].val: 0;
    return acc.concat([{ val, color }])
}, [])

решение вашей проблемы.

проблемы:

  1. неправильное начальное значение
  2. возвращаемый объект

хотя я думаю, что здесь лучше выбрать карту.

...