最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Use reduce to sum values in array of objects - Stack Overflow

programmeradmin4浏览0评论

I have this array of objects:

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

This is what I would like to obtain:

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

So each item should have the same color and the cumulative value of previous data.

This is what I try:

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)

I have this array of objects:

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

This is what I would like to obtain:

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

So each item should have the same color and the cumulative value of previous data.

This is what I try:

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)

Where is the error? Why r[i - 1] is undefined?

Share Improve this question asked Jul 14, 2020 at 14:46 mariellemarielle 4482 gold badges16 silver badges47 bronze badges 2
  • The seed data[0] is incorrect. It should be [] because you want it to result into a new array. Additionally, build up this array, you need to return [...r, newDatum], not newDatum – Aluan Haddad Commented Jul 14, 2020 at 14:51
  • reduce function return a single value. in this case, you need to use map function. – Ikram Ud Daula Commented Jul 14, 2020 at 14:55
Add a ment  | 

3 Answers 3

Reset to default 6

You had four issues in your code:

  • In this line const cumVal = i === 0 ? val : r[i - 1].val you should assign 0 as a default value, not val
  • In this line const newDatum = { val: cumVal, color } you need to add val to cumVal
  • As an initial value, you should pass an empty array, not the first element of your data array, because you want to have an array as a result, not an object
  • You need to return the r in every iteration, not newDatum - again, you want to have an array in the end, not an object

Here is a fixed version:

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)

You start the reduce with a single element, which is not an array.

Instead, you could take a closure over sum and map new objects.

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 result2 = data.reduce((acc, { val, color }, i) => {
    val += (i>0) ? acc[i - 1].val: 0;
    return acc.concat([{ val, color }])
}, [])

the solution to your problem.

issues:

  1. wrong initial value
  2. returning object

though I think Map would be a better choice here.

发布评论

评论列表(0)

  1. 暂无评论