7

This is probably a 2 liner, but for some reason I have hit a wall.

I'd like to convert an array of objects to an object of key-value pairs.

So this:

var items = [
    {
      name: 'hello',
      value: ['one', 'two']
    },
    {
      name: 'hi',
      value: ['one', 'two', 'three']
    }
]

to this:

var items = {
    'hello': ['one', 'two'],
    'hi': ['one', 'two', 'three']
}

Is this really the most elegant way?

const newObj = {};
items.forEach((item) => {
  newObj[item.name] = item.value;
});

I'd like to use ES6 arrow functions preferably. Also, can someone tell me if you think it would be easier to manipulate this data in the first or second format? For context, I am trying to teach myself topological sorts.

bspckl
  • 197
  • 1
  • 9
  • 2
    One could also do `Object.fromEntries(items.map(({ name, value }) => [name, value]))` ... but if that's more elegant, I dunno. – Jonas Wilms Apr 18 '20 at 22:18
  • 1
    Does this answer your question? [How do I convert array of Objects into one Object in JavaScript?](https://stackoverflow.com/questions/19874555/how-do-i-convert-array-of-objects-into-one-object-in-javascript) – Ivar Dec 05 '22 at 08:28

5 Answers5

7

I would do that with Array.prototype.reduce(), it is even more concise and certainly faster than Object.fromEntries():

const items = [{name:'hello',value:['one','two']},{name:'hi',value:['one','two','three']}], 

result = items.reduce((r,{name,value}) => (r[name]=value,r), {})

console.log(result)
.as-console-wrapper{min-height:100%;}
Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
6

A more concise method would be to use Object.fromEntries:

var items = [
    {
      name: 'hello',
      value: ['one', 'two']
    },
    {
      name: 'hi',
      value: ['one', 'two', 'three']
    }
];
const newObj = Object.fromEntries(
  items.map(({ name, value }) => [name, value])
);
console.log(newObj);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • @bspckl : if you plan to handle with this some large datasets and you require *certain performance*, there're even more concise and [**fast**](https://jsbench.me/tck967ysqe/1) options around ;) – Yevhen Horbunkov Apr 18 '20 at 22:57
1

Use Object.values and Object.fromEntries to simplify into one line

Object.fromEntries(items.map(item => Object.values(item)))

var items = [
  {
    name: "hello",
    value: ["one", "two"]
  },
  {
    name: "hi",
    value: ["one", "two", "three"]
  }
];

const res = Object.fromEntries(items.map(item => Object.values(item)));

console.log(res);
Siva K V
  • 10,561
  • 2
  • 16
  • 29
  • If you were targeting for ultimate conciseness, you could've done `Object.fromEntries(items.map(Object.values))` or, doing code golf all the way through, `with(Object)fromEntries(arr.map(values))`. – Yevhen Horbunkov Dec 13 '21 at 12:50
0

I don't know if this is more elegant but I think reduce make sence here.

var items = [
    {
      name: 'hello',
      value: ['one', 'two']
    },
    {
      name: 'hi',
      value: ['one', 'two', 'three']
    }
];


const newObj = items.reduce((c, {value, name}) => {
  c[name] = value;
  return c;
}, {});

console.log(newObj);
Cedric Cholley
  • 1,956
  • 2
  • 9
  • 15
0

Simply by mapping each array elements:

use map() method:

const newObj = {};
items.map( ( { name, value } ) => {
    newObj[name] = value;
});

EDIT:

use forEach() method:

const newObj =
((obj) => {
    items.forEach(({ name, value }) => { obj [name] = value });
    return obj;
 })({});

JavaScript: Difference between .forEach() and .map()

OO7
  • 660
  • 4
  • 10
  • That is somewhat unconventional use of `map()` method, since it is expected to return array of the same size as input, so, considering you simply use it for looping and do necessary actions (assign `newObj` properties) alongside, you'd be way better off with `Array.prototype.forEach()` – Yevhen Horbunkov Apr 19 '20 at 21:52
  • Really? So what's the different between map() method vs forEach() method? – OO7 Apr 20 '20 at 17:11