如何使用不可变JS更新List中的元素?

这是官方文档所说的

updateIn(keyPath: Array<any>, updater: (value: any) => any): List<T>
updateIn(keyPath: Array<any>, notSetValue: any, updater: (value: any) => any): List<T>
updateIn(keyPath: Iterable<any, any>, updater: (value: any) => any): List<T>
updateIn(keyPath: Iterable<any, any>, notSetValue: any, updater: (value: any) => any): List<T>

普通的Web开发人员(不是函数式程序员)无法理解这一点!

我有非常简单(对于非功能性方法)的情况。

var arr = [];
arr.push({id: 1, name: "first", count: 2});
arr.push({id: 2, name: "second", count: 1});
arr.push({id: 3, name: "third", count: 2});
arr.push({id: 4, name: "fourth", count: 1});
var list = Immutable.List.of(arr);

如何更新名称为第三的元素的计数设置为4的位置?list


答案 1

最合适的情况是同时使用和方法。findIndexupdate

list = list.update(
  list.findIndex(function(item) { 
    return item.get("name") === "third"; 
  }), function(item) {
    return item.set("count", 4);
  }
); 

附言:并不总是可以使用地图。例如,如果名称不是唯一的,并且我想更新具有相同名称的所有项目。


答案 2

使用 .setIn() 您可以执行相同的操作:

let obj = fromJS({
  elem: [
    {id: 1, name: "first", count: 2},
    {id: 2, name: "second", count: 1},
    {id: 3, name: "third", count: 2},
    {id: 4, name: "fourth", count: 1}
  ]
});

obj = obj.setIn(['elem', 3, 'count'], 4);

如果我们不知道要更新的条目的索引。使用 .findIndex() 很容易找到它:

const indexOfListToUpdate = obj.get('elem').findIndex(listItem => {
  return listItem.get('name') === 'third';
});
obj = obj.setIn(['elem', indexOfListingToUpdate, 'count'], 4);

希望它有帮助!