How to create an object from an Array of key-value pairs?

In Python one can pass the dict1 constructor a sequence of key-value pairs:

>>> dict([['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']])
{'age': 42, 'name': 'Bob', 'breakfast': 'eggs'}

I can't think of any way to do this sort of thing in JavaScript other than defining my own function for the purpose:

function pairs_to_object(pairs) {
    var ret = {};
    pairs.forEach(function (p) { ret[p[0]] = p[1]; });
    return ret;
}

But I'm a JS noob... Is there anything built-in for this sort pairs-to-object conversion?

1 For the purposes of this question, I'm treating Python dicts as Python's counterpart of JS objects, although, of course the similarity is limited only to the fact that they are both key-value collections.


Solution 1:

Object.fromEntries does the job. It was added to the language with EcmaScript2019.

If you don't have support for that function, you could define it yourself with the following ES2015 code:

Object.fromEntries = arr => Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));

A nice thing is that this method does the opposite of Object.entries (ES2017), so now you can go back and forth between the object and array representation:

const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const obj = Object.fromEntries(arr);
console.log(obj);
// ... and back:
const arr2 = Object.entries(obj);
console.log(arr2); // copy of the original array (omitting duplicate keys)
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6 Map

There is an alternative to plain objects for key/value pairs: Map.

Its constructor accepts the array-of-pairs format:

// Demo:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];

const mp = new Map(arr);

// Get one particular value:
console.log(mp.get('age'));
// Get all the keys:
console.log(...mp.keys());
// Get all the values:
console.log(...mp.values());
// Get all the key/value pairs:
console.log(...mp.entries());

If you really need a plain object, then this is not useful, but a Map might present a viable alternative.

Solution 2:

You can use the reduce function

x = [[1,2],[3,4],[5,6]];
o = x.reduce(function(prev,curr){prev[curr[0]]=curr[1];return prev;},{})

o is now the equivalent of {1:2, 3:4, 5:6}

If your input array is sparse, you'll want to add a if(curr!=undefined) test on the assignment, but make sure you still return "prev".

If your tuples are something more complex than simple [key,value], you can simply change the way "prev" is assigned to. Eg: prev["key-"+curr[0].toString()]=curr[1]*2;

Solution 3:

At the time of writing (2013) JavaScript objects / dictionaries / associative arrays don't have such a constructor natively.

As you said yourself, you can of course build your own function using for instance a functional approach using the reduce function as explained in one of the other answers. A classic for or newer forEach loop would also work, of course. But there isn't anything built-in.


Edit: It's 2019 and now we have Object.fromEntries, which will give you what you need.

Solution 4:

Lodash's fromPairs function will do this:

const _ = require('lodash')
const kvPairs = [['a', 1], ['b', 2]]
_.fromPairs(kvPairs)
// => { a: 1, b: 2 }