-1

The code is like this

const reducer = (accumlator, currentVal) => accumlator.push( {id: currentVal} );

const ids = ['123', '456'];

// want to get [{id:123}, {id:456}]
const rs = ids.reduce(reducer, []);

console.log(rs);

But says: TypeError: accumlator.push is not a function at reducer (/home/user/list1.js:2:56) at Array.reduce ()

Any suggestions ?

user3552178
  • 2,719
  • 8
  • 40
  • 67
  • The reducer callback needs to return the array, ie return `accumlator`. `reduce()` takes the returned value from the callback and uses it as the first argument to be passed to the next iteration call to the callback. – Patrick Evans Nov 06 '20 at 22:31

1 Answers1

4

push does not return the array; rather it returns undefined. Therefore, for the first iteration, accumulator will be the empty array, but for the second iteration it will be undefined.

I'd recommend concat instead:

const ids = ['123', '456'];

// want to get [{id:123}, {id:456}]
const rs = ids.reduce((accumlator, currentVal) => accumlator.concat([{id: currentVal}]), []);

...or use map for a simpler implementation:

const rs = ids.map(id => ({ id }));
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • Thanks for the nice answer, especially the map implementation ! BTW, in the map way, why it's id => ({id}) instead of id => {id} please ? – mike652638 May 13 '21 at 03:35
  • 1
    It's because of syntax quirks of JavaScript. `{}` is for defining a code block and it's also for defining an object literal. If you do an arrow function `id => { id }` it thinks there's a code block with the useless statement `id` which means a function that returns nothing, so you'd get an `Array` of `undefined` values instead of what you want. By wrapping in parentheses, this lets the parser know it's an expression instead of a code block, so it'll use `{}` to construct an object with the property `id` instead. – Jacob May 13 '21 at 17:19