Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I transform a List of Maps into a Map of Maps in immutable.js?

Tags:

Suppose I have an immutable.js List like this:

var xs = Immutable.fromJS([{key: "k", text: "foo"}]) 

I want to transform that into a Map that looks like this:

var ys = Immutable.fromJS({k: {key: "k", text: "foo"}}) 

How do I turn xs into ys idiomatically in immutable.js?

By idiomatically I mean that any intermediate structures should be immutable.js structures, and I think that any intermediate steps would use iterable composition instead of creating full-size intermediate representations.

Edit: I've created a jsperf benchmark comparing the answers provided so far. Both non-mutating solutions feel fairly idiomatic to me; I may hold out and let votes decide the chosen answer or hold out until we can gather a collection of roughly equally idiomatic techniques.

like image 206
CJ Gaconnet Avatar asked Apr 11 '15 03:04

CJ Gaconnet


People also ask

Are JavaScript maps immutable?

js provides many Persistent Immutable data structures including: List , Stack , Map , OrderedMap , Set , OrderedSet and Record .

What is a map in immutable js?

The Immutable. js Map() is analogous to a Javascript Object or Hash since it is comprised of key-value pairs. The Immutable. js List() is analogous to a Javascript Array and contains many of the same native methods.

Is map function immutable?

Map's keys can be of any type, and use Immutable.is to determine key equality. This allows the use of any value (including NaN) as a key. Because Immutable.is returns equality based on value semantics, and Immutable collections are treated as values, any Immutable collection may be used as a key.

Which presents a Mutative API which does not update the data in place?

Persistent data presents a mutative API which does not update the data in-place, but instead always yields new updated data.


2 Answers

You can reduce the input list into new Immutable.Map:

var ys = xs.reduce(       function(result, item) { return result.set(item.get('key'), item); },        Immutable.Map()); 

There is no intermediate representation in this case, but the immutable map has to be updated (in fact, new instance must be created) in every iteration and that that can be suboptimal (depending on the actual implementation of Immutable.Map).

You can optimize it reducing into regular javascript object and convert it to immutable map at the end:

var ys = Immutable.Map(xs.reduce(       function(result, item) { result[item.get('key')] = item; return result; },        {})); 

But that is certainly less idiomatic.

like image 141
dkl Avatar answered Oct 11 '22 13:10

dkl


One solution may be to use Map constructor from List:

const ys = Immutable.Map(xs.map(v => [v.get('key'), v])); 
like image 20
Julien Deniau Avatar answered Oct 11 '22 12:10

Julien Deniau