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?
-
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 toreturn [...r, newDatum]
, notnewDatum
– Aluan Haddad Commented Jul 14, 2020 at 14:51 -
reduce
function return a single value. in this case, you need to usemap
function. – Ikram Ud Daula Commented Jul 14, 2020 at 14:55
3 Answers
Reset to default 6You had four issues in your code:
- In this line
const cumVal = i === 0 ? val : r[i - 1].val
you should assign0
as a default value, notval
- In this line
const newDatum = { val: cumVal, color }
you need to addval
tocumVal
- 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, notnewDatum
- 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:
- wrong initial value
- returning object
though I think Map would be a better choice here.