提问者:小点点

在对象数组中使用reduce to sum值


我有这样的对象数组:

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'}
]

所以每个项目都应该有相同的颜色和以前数据的累计值。

这就是我所尝试的:

null

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)

null

错误在哪里? 为什么R[I-1]未定义?


共3个答案

匿名用户

使用单个元素启动reduce,该元素不是数组。

相反,您可以在sum上使用闭包并映射新对象。

null

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);

匿名用户

您的代码中有四个问题:

  • 在这行const cumVal=i===0? val:r[i-1]。val应将0指定为默认值,而不是将val
  • 指定为默认值
  • 在这一行const newDatum={val:cumVal,color}中,您需要将val添加到cumVal
  • 作为初始值,应传递空数组,而不是data数组的第一个元素,因为您希望结果是数组,而不是对象
  • 您需要在每次迭代中返回r,而不是newdatum-同样,您希望在最后有一个数组,而不是一个对象

这里有一个固定版本:

null

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)

匿名用户

var result2 = data.reduce((acc, value, i) => {
    let { val, color } = value
    val += (i>0) ? acc[i - 1].val: 0;
    const newDatum = { val, color }
    return acc.concat([newDatum])
}, [])

解决你问题的方法。

问题:

  1. 初始值错误
  2. 返回对象