不可变的 JS 映射或列表

Immutable JS map or list

假设我们有一个简单的 javascript 对象数组

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

我们想将它引入 immutablejs。将其制作成地图或列表是最自然的吗?我们如何更新其中一个对象中的 属性?假设将 "Hartford Whalers" 的名称更改为 "Carolina Hurricanes"。

您应该为此创建一个地图列表。 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" } ]"

我不同意。

您给数组的每个元素的示例是一个具有 { id } 属性 的对象。人们会假设您希望通过其 id 访问该数组的元素。这就是 ID 的用途。

是的,原生结构是 MapsList。虽然你想要的是 Map of 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,则在服务器端进行转换,这称为规范化。它还具有节省数据的好处。

这实际上就是“地图”一词的来源