使用 reduce 对对象数组中的值求和
Use reduce to sum values in array of objects
我有这个对象数组:
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]
未定义?
你从一个元素开始 reduce,它不是一个数组。
相反,您可以关闭 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);
您的代码中有四个问题:
- 在这一行
const cumVal = i === 0 ? val : r[i - 1].val
中,您应该指定 0
作为默认值,而不是 val
- 在这一行
const newDatum = { val: cumVal, color }
你需要添加 val
到 cumVal
- 作为初始值,您应该传递一个空数组,而不是
data
数组的第一个元素,因为您希望得到一个数组作为结果,而不是一个对象
- 你需要在每次迭代中 return
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)
const result2 = data.reduce((acc, { val, color }, i) => {
val += (i>0) ? acc[i - 1].val: 0;
return acc.concat([{ val, color }])
}, [])
您的问题的解决方案。
问题:
- 初始值错误
- 返回对象
though I think Map would be a better choice here.
我有这个对象数组:
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]
未定义?
你从一个元素开始 reduce,它不是一个数组。
相反,您可以关闭 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);
您的代码中有四个问题:
- 在这一行
const cumVal = i === 0 ? val : r[i - 1].val
中,您应该指定0
作为默认值,而不是val
- 在这一行
const newDatum = { val: cumVal, color }
你需要添加val
到cumVal
- 作为初始值,您应该传递一个空数组,而不是
data
数组的第一个元素,因为您希望得到一个数组作为结果,而不是一个对象 - 你需要在每次迭代中 return
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)
const result2 = data.reduce((acc, { val, color }, i) => {
val += (i>0) ? acc[i - 1].val: 0;
return acc.concat([{ val, color }])
}, [])
您的问题的解决方案。
问题:
- 初始值错误
- 返回对象
though I think Map would be a better choice here.