0

I have an array of key-value pairs:

const arr = [
  { key: 'One', value: '1' },
  { key: 'Two', value: '2' },
  { key: 'Three', value: '3' }
];

I would like to convert the above array into this kind of object:

const obj = {
  'One': '1',
  'Two': '2',
  'Three': '3'
}

by using the Array.reduce() function. This is what have I done so far:

const obj = arr.reduce( (prev, curr) => prev[curr.key] = curr.value, {} );

which is not working because, on the second run of the reduce function, prev is undefined and therefore I get this error:

ERROR Error: Uncaught (in promise): TypeError: Cannot set property 'Two' of undefined

I thought I would be able to compose obj at each reduce iteration... What am I doing wrong?

Andrea
  • 675
  • 1
  • 13
  • 34

4 Answers4

2

You could use Object.assign inside the reduce method.

const arr = [{ key: 'One', value: '1' },{ key: 'Two', value: '2' },{ key: 'Three', value: '3' }];
const obj = arr.reduce( (prev, {key, value}) => Object.assign(prev, {[key]: value}), {} );
console.log(obj)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
2

You can destructure the the object to get the key and the value properties. Then use object spread, and computed property names to add the key and value to the prev object:

const arr = [
  { key: 'One', value: '1' },
  { key: 'Two', value: '2' },
  { key: 'Three', value: '3' }
];

const obj = arr.reduce( (prev, { key, value }) => ({ ...prev, [key]: value }), {});

console.log(obj);

Another option is to use Array.map(), and convert each object to this form - { [key]: value }. Then merge everything by spreading into Object.assign():

const arr = [
  { key: 'One', value: '1' },
  { key: 'Two', value: '2' },
  { key: 'Three', value: '3' }
];

const obj = Object.assign(...arr.map(({ key, value }) => ({ [key]: value })));

console.log(obj);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
2

You got undefined because prev doesn't have the attribute in prev[curr.key].

Here is my solution:

const arr = [
  { key: 'One', value: '1' },
  { key: 'Two', value: '2' },
  { key: 'Three', value: '3' }
];

const result = arr.reduce((prev, curr) => {
  return {
    ...prev,
    [curr.key]: curr.value
  }
}, {});

console.log(result);
deerawan
  • 8,002
  • 5
  • 42
  • 51
1

You choose the right function, however, the only missing part was the value returned for each item was not the accumulator (object in our case). Ensuring this will fix your problem.

const arr = [{ key: 'One', value: '1' },{ key: 'Two', value: '2' },{ key: 'Three', value: '3' }];

const obj = arr.reduce( (prev, curr) => {
  prev[curr.key] = curr.value;
  return prev;
}, {});

console.log(obj);
Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59