swelet
swelet

Reputation: 8702

Immutable JS map or list

Say we have a plain javascript array of objects

[
  {id : 1, name : "Hartford Whalers"}, 
  {id : 2, name : "Toronto Maple Leafs"}, 
  {id : 3, name : "New York Rangers"}
]

and we wanted to bring it in to immutablejs. Would it be most natural to make it into a map or a list, and how would we update a property in one of the objects? Say change the name of "Hartford Whalers" to "Carolina Hurricanes".

Upvotes: 3

Views: 4824

Answers (2)

AndrewMcLagan
AndrewMcLagan

Reputation: 13987

I disagree.

The example you give each element of the array is an object that has an { id } property. One would assume you will want to access the elements of this array via their id. thats what ids are for.

Yes the native structure is a List of Maps. Although what you want is a Map of Maps.

Why?

Think about what you will need to do to retrieve { id: 1928, "Some Team" }. You would have to iterate one-by-one through the list till you found your matching Id.

A far more efficient way to do this is create a map so you can directly "pluck" your object e.g.

const input = Immutable.fromJS({
  1: {id : 1, name : "Hartford Whalers"}, 
  2: {id : 2, name : "Toronto Maple Leafs"}, 
  3: {id : 3, name : "New York Rangers"},
  // ...
  1928: {id : 1928, name : "Some Team"},
});

Then to access it all you have to do is:

const team = input.get('1928');

you need to do the initial conversion, do that server-side if its coming from an API, its called normalisation. It has the benefit of saving data as well.

This is actually where the term "map" comes from

Upvotes: 1

Dogbert
Dogbert

Reputation: 222108

You should create a List of Maps for this. Immutable.js has a function Immutable.fromJS that will recursively convert JS Arrays to Immutable.List and JS Objects to Immutable.Map.

var input = [
  {id : 1, name : "Hartford Whalers"}, 
  {id : 2, name : "Toronto Maple Leafs"}, 
  {id : 3, name : "New York Rangers"}
];

var list = Immutable.fromJS(input);

list.toString(); // => "List [ Map { "id": 1, "name": "Hartford Whalers" }, Map { "id": 2, "name": "Toronto Maple Leafs" }, Map { "id": 3, "name": "New York Rangers" } ]"

You can set the name of the first item using .setIn:

var list2 = list.setIn([0, "name"], "Carolina Hurricanes");

list2.toString(); // => "List [ Map { "id": 1, "name": "Carolina Hurricanes" }, Map { "id": 2, "name": "Toronto Maple Leafs" }, Map { "id": 3, "name": "New York Rangers" } ]"

You can set the name of any item with name = "Hartford Whalers" to "Carolina Hurricanes" :

var list3 = list.map(function(item) {
  if(item.get("name") == "Hartford Whalers") {
    return item.set("name", "Carolina Hurricanes");
  } else {
    return item;
  }
});

list3.toString(); // => "List [ Map { "id": 1, "name": "Carolina Hurricanes" }, Map { "id": 2, "name": "Toronto Maple Leafs" }, Map { "id": 3, "name": "New York Rangers" } ]"

Upvotes: 5

Related Questions