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
。由于我们不能使用mutation,而需要调用一个方法,因此我们可以使用:counts.set(2, 4)
-表示4
在index处设置值2
。
深度更新
您给出的示例虽然具有嵌套数据。我们不能只使用set()
初始集合。
Immutable.js集合具有一系列方法,其名称以“ In”结尾,这使您可以在嵌套集中进行更深的更改。最常见的更新方法具有相关的“输入”方法。例如set
有setIn
。这些“ In”方法不接受索引或键作为第一个参数,而是接受“键路径”。密钥路径是一组索引或密钥,它们说明了如何获取要更新的值。
在您的示例中,您想要更新列表中索引2处的项目,然后更新该项目中键“ count”处的值。因此,关键路径将是[2, "count"]
。该setIn
方法的第二个参数就像一样工作set
,它是我们要放入的新值,因此:
list = list.setIn([2, "count"], 4)
找到正确的密钥路径
更进一步,您实际上说过您想更新名称为“ 3”的项目,该名称与第3个项目不同。例如,也许您的列表未排序,或者早些时候删除了名为“ two”的项目?这意味着首先我们需要确保我们确实知道正确的密钥路径!为此,我们可以使用findIndex()
方法(顺便说一下,它的工作原理几乎与Array#findIndex一样)。
一旦我们在列表中找到了要更新的项目的索引,就可以提供要更新的值的关键路径:
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
注意:Set
vsUpdate
最初的问题提到的是更新方法,而不是set方法。我将解释该函数中的第二个参数(称为updater
),因为它不同于set()
。而第二个参数set()
是我们想要的新的价值,第二个参数update()
是一个函数,它接受先前的值,并返回,我们希望新的价值。然后,updateIn()
是“ In”变体update()
接受密钥路径。
举例来说,我们想要您的示例的一种变体,它不仅将count设置为4
,而是增加了现有计数,我们可以提供一个将现有值增加一个的函数:
var index = list.findIndex(item => item.name === "three")
list = list.updateIn([index, "count"], value => value + 1)