I was trying to solve another person's problem on SO using Array.prototype.reduce
and ...object
destructuring. I don't understand why it works as expected when I'm using Object.assign
, but not when using the spread operator.
const str = 'Jack:13,Phil:15,Lucy:12'
const arr = str.split(',')
let reducer = (acc, val) => {
return { ...acc,
...{
[val.split(':')[0]]: Number(val.split(':')[1])
}
}
}
let reducer2 = (acc, val) => {
return Object.assign(acc, {
[val.split(':')[0]]: Number(val.split(':')[1])
})
}
let obj = {
Jody: 29
}
let obj2 = {
Julie: 28
}
arr.reduce(reducer, obj)
arr.reduce(reducer2, obj2)
console.log(obj)
/* output:
{
"Jody": 29
}
*/
console.log(obj2)
/* output:
{
"Julie": 28,
"Jack": 13,
"Phil": 15,
"Lucy": 12
}
*/
Array reduce
is often used to return a new value. Even if it mutates an accumulator, it's safe to assume that it can return a new value.
arr.reduce(reducer, obj)
relies on that obj
is mutated. reducer2
mutates original object indeed, this is the reason why it works. But this contradicts with reducer
which keeps an accumulator immutable.
It should be:
obj = arr.reduce(reducer, obj);