Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Javascript a dictionary comprehension, or an Object `map`

I need to generate a couple of objects from lists in Javascript. In Python, I'd write this:

{key_maker(x): val_maker(x) for x in a_list}

Another way to ask is does there exist something like jQuery.map() which aggregates objects? Here's my guess (doesn't work):

var result = {}
$.map(a_list, function(x) {
    $.extend(result, {key_maker(x): val_maker(x)})
})
like image 513
Cuadue Avatar asked Jun 17 '12 01:06

Cuadue


People also ask

What is the list comprehension in JavaScript?

A list comprehension is a certain language syntax available in many programming languages. It is used for creating a new list from an already existing list. You can think of list comprehension as an elegant way to filter a list.

Does JavaScript support list comprehension?

Yes, JavaScript will support array comprehensions in the upcoming EcmaScript version 7.

Is there Dictionary comprehension in Python?

Like List Comprehension, Python allows dictionary comprehensions. We can create dictionaries using simple expressions.


6 Answers

Assuming a_list is an Array, the closest would probably be to use .reduce().

var result = a_list.reduce(function(obj, x) {
    obj[key_maker(x)] = val_maker(x);
    return obj;
}, {});

Array comprehensions are likely coming in a future version of JavaScript.


You can patch non ES5 compliant implementations with the compatibility patch from MDN.


If a_list is not an Array, but a plain object, you can use Object.keys() to perform the same operation.

var result = Object.keys(a_list).reduce(function(obj, x) {
    obj[key_maker(a_list[x])] = val_maker(a_list[x]);
    return obj;
}, {});
like image 145
3 revs, 2 users 94%user1106925 Avatar answered Oct 12 '22 00:10

3 revs, 2 users 94%user1106925


Old question, but the answer has changed slightly in new versions of Javascript. With ES2015 (ES6) you can achieve a one-liner object comprehension like this:

a_list.reduce((obj, x) => Object.assign(obj, { [key_maker(x)]: value_maker(x) }), {})
like image 35
benwixen Avatar answered Oct 12 '22 00:10

benwixen


Maybe something like this, using Lodash: var result = _.fromPairs(a_list.map(x => [key_maker(x), value_maker(x)]));

like image 20
Elias Zamaria Avatar answered Oct 12 '22 01:10

Elias Zamaria


Here's a version that doesn't use reduce:

Object.fromEntries( a_list.map( x => [key_maker(x), value_maker(x)]) );

Object.fromEntries is basically the same as _.fromPairs in Lodash. This feels the most like the Python dict comprehension to me.

like image 32
fizzyh2o Avatar answered Oct 11 '22 23:10

fizzyh2o


ES5 introduced Map for an OrderedDict. A Map comprehension might look like:

Map( Array.map(function(o){return[ key_maker(o), val_maker(o) ]}))

Example:

> a_list = [ {x:1}, {x:2}, {x:3} ]
< [ Object, Object, Object ]
>
> let dict = new Map(a_list.map(function(o){return[ o.x, o.x**2 ]}))
< Map[3]
< 0 : {1 => 1}
< 1 : {2 => 4}
< 2 : {3 => 9}
>
> dict.get(2)
< 4
like image 38
Steven Almeroth Avatar answered Oct 11 '22 23:10

Steven Almeroth


A shorter ES6 version would be:

a_list.reduce((obj, x) => (obj[key_maker(x)] = val_maker(x), obj),{})
like image 24
smartexpert Avatar answered Oct 12 '22 01:10

smartexpert