24

What is the fastest algorithm for getting from something like this:

var array = [ [1,'a'], [2,'b'], [3,'c'] ];

to something like this:

Object { 1: "a", 2: "b", 3: "c" }

so far this is what i've come up with:

function objectify(array) {
    var object = {};
    array.forEach(function(element) {
        object[element[0]] = element[1];
    });
    return object;
}

which works fine, but it seems kind of clumsy. Is there a better way? Would something like reduce() work and would that be any faster?

5 Answers 5

35

You can use Object.fromEntries to convert an Array to an Object:

var array = [
  [1, 'a'],
  [2, 'b'],
  [3, 'c']
];
var object = Object.fromEntries(array);
console.log(object);

Sign up to request clarification or add additional context in comments.

2 Comments

This is the "correct" answer, and much nicer than the reduce approach. Only use reduce if you need to target very old browsers (eg IE)
What an elegant way of getting things done. This code snippet does the job without any further complications.
22

You could indeed use Array.prototype.reduce:

function objectify(array) {
    return array.reduce(function(p, c) {
         p[c[0]] = c[1];
         return p;
    }, {});
}

where p is the result of the previous iteration, initially {}, and c is the current element of the array.

It's unlikely to be any faster than array.forEach, but it is IMHO cleaner. I don't believe there's any simpler implementation than this.

NB: a function to do exactly this already exists in the Underscore library: _.object(array)

Comments

9

Terse version using modern syntax:

let objectify = a => a.reduce( (o,[k,v]) => (o[k]=v,o), {} );

I use this technique as part of a terse query string parser:

// Converts "?foo=bar&j=1&go" into { foo:'bar', j:'1', go:true }
function parseQueryString(qs) {
    var q = decodeURIComponent;
    return qs.replace(/^\?/,'').split('&').map(s => s.split('='))
             .reduce((o,[k,v]) => (o[q(k)] = v?q(v):true, o), {});
}

2 Comments

This works perfectly for my use case. I consider myself pretty proficient in ESXXXX but I can't quite figure out how that lambda is working. Specifically the (o[k]=v,o) part. Any insights? Also, thanks for sharing this gem. :-)
@KyleFarris it's using the comma operator to perform the assignment into the map, and then return o itself.
7

Lodash has a _.fromPairs method that does exactly that.

From the documentation:

_.fromPairs([['a', 1], ['b', 2]]);
// => { 'a': 1, 'b': 2 }  

Comments

2

You can wrap the entire thing within Array.prototype.reduce, like this

function objectify(array) {
    return array.reduce(function(result, currentArray) {
        result[currentArray[0]] = currentArray[1];
        return result;
    }, {});
}

console.log(objectify([ [1, 'a'], [2, 'b'], [3, 'c'] ]));
# { '1': 'a', '2': 'b', '3': 'c' }

We are just accumulating the key-value pairs in the result object and finally the result of reduce will be the result object and we are returning it as the actual result.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.