以下是官方文件所说的
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);
如何更新list
,其中名为third的元素的count设置为4
发布于 2015-04-16 00:07:13
最合适的情况是同时使用findIndex
和update
方法。
list = list.update(
list.findIndex(function(item) {
return item.get("name") === "third";
}), function(item) {
return item.set("count", 4);
}
);
附注:使用地图并不总是可行的。例如,如果名称不是唯一的,而我想要更新具有相同名称的所有项目。
发布于 2016-09-30 17:46:20
使用.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);
希望它能帮上忙!
发布于 2016-12-03 04:16:51
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
说明
更新Immutable.js集合总是返回这些集合的新版本,保持原始版本不变。正因为如此,我们不能使用JavaScript的list[2].count = 4
突变语法。相反,我们需要调用方法,就像我们可能对Java集合类所做的那样。
让我们从一个更简单的例子开始:只计算列表中的计数。
var arr = [];
arr.push(2);
arr.push(1);
arr.push(2);
arr.push(1);
var counts = Immutable.List.of(arr);
现在,如果我们想要更新第三项,一个普通的JS数组可能看起来像:counts[2] = 4
。因为我们不能使用突变,并且需要调用一个方法,所以我们可以使用:counts.set(2, 4)
-这意味着在索引2
处设置值4
。
深度更新
不过,您给出的示例中包含嵌套数据。我们不能只在初始集合上使用set()
。
Immutable.js集合有一系列名称以" in“结尾的方法,允许您在嵌套的集合中进行更深层次的更改。大多数常见的更新方法都有一个相关的"In“方法。例如,对于set
,就有setIn
。这些"In“方法接受”键路径“,而不是接受索引或键作为第一个参数。键路径是一个索引或键的数组,它说明了如何获得您希望更新的值。
在您的示例中,您希望更新列表中索引为2的项目,然后更新该项目中关键字"count“处的值。所以关键路径应该是[2, "count"]
。setIn
方法的第二个参数的工作方式与set
类似,它是我们要放入其中的新值,因此:
list = list.setIn([2, "count"], 4)
查找正确的密钥路径
更进一步,你实际上说你想要更新名称为"three“的项目,这与第三个项目不同。例如,可能您的列表没有排序,或者名为"two“的项之前被删除了?这意味着首先我们需要确保我们确实知道正确的密钥路径!为此,我们可以使用findIndex()
方法(顺便说一句,它的工作方式与Array#findIndex几乎完全相同)。
一旦我们在列表中找到了包含我们想要更新的项的索引,我们就可以提供我们想要更新的值的键路径:
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
NB: Update
vs.
最初的问题提到的是update方法,而不是set方法。我将解释该函数中的第二个参数(称为updater
),因为它不同于set()
。set()
的第二个参数是我们想要的新值,而update()
的第二个参数是一个函数,它接受前一个值并返回我们想要的新值。然后,updateIn()
是update()
的"In“变体,它接受密钥路径。
例如,我们想要你的例子的一个变体,它不只是将计数设置为4
,而是增加现有的计数,我们可以提供一个函数,将现有值加1:
var index = list.findIndex(item => item.name === "three")
list = list.updateIn([index, "count"], value => value + 1)
https://stackoverflow.com/questions/29589753
复制相似问题