不可变的JS地图或列表

时间:2016-04-29 08:59:36

标签: javascript immutable.js

假设我们有一个普通的javascript对象数组

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

我们想把它带到immutablejs。将它变成地图或列表是最自然的,我们如何更新其中一个对象的属性?比如说将“哈特福德捕鲸者”的名称改为“卡罗莱纳飓风”。

2 个答案:

答案 0 :(得分:3)

您应该为此创建地图列表。 Immutable.js有一个函数Immutable.fromJS,它将递归地将JS数组转换为Immutable.List,将JS对象转换为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" } ]"

您可以使用.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" } ]"

您可以将名称=“Hartford Whalers”的任何项目的名称设置为“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" } ]"

答案 1 :(得分:1)

我不同意。

您为数组的每个元素提供的示例是一个具有{ id }属性的对象。人们会假设你想通过他们的id访问这个数组的元素。那是什么ids。

是的,原生结构是List Maps。虽然你想要的是Map Maps

为什么?

考虑一下检索{ id: 1928, "Some Team" }需要做些什么。您必须通过列表迭代逐个,直到找到匹配的ID。

更有效的方法是创建一个地图,这样你就可以直接“采摘”你的对象,例如。

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"},
});

然后要访问它,您所要做的就是:

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

你需要进行初始转换,如果它来自API,则执行该服务器端,称为规范化。它还具有保存数据的好处。

这实际上是“地图”一词来自