var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
объяснение
Обновление коллекций Immutable.js всегда возвращает новые версии этих коллекций, оставляя исходную неизменной. Из-за этого мы не можем использовать list[2].count = 4
синтаксис мутации JavaScript . Вместо этого нам нужно вызывать методы, как и в случае с классами коллекций Java.
Начнем с более простого примера: просто счетчики в списке.
var arr = [];
arr.push(2);
arr.push(1);
arr.push(2);
arr.push(1);
var counts = Immutable.List.of(arr);
Теперь , если мы хотим , чтобы обновить 3 - й пункт, простой массив JS может выглядеть следующим образом : counts[2] = 4
. Поскольку мы не можем использовать мутацию и должны вызвать метод, вместо этого мы можем использовать: counts.set(2, 4)
- это означает установить значение 4
в индексе 2
.
Глубокие обновления
Однако в приведенном вами примере есть вложенные данные. Мы не можем просто использовать set()
исходную коллекцию.
Коллекции Immutable.js имеют семейство методов с именами, оканчивающимися на «In», которые позволяют вносить более глубокие изменения во вложенный набор. Наиболее распространенные методы обновления имеют связанный метод «In». Например, set
есть setIn
. Вместо того, чтобы принимать индекс или ключ в качестве первого аргумента, эти методы «In» принимают «путь ключа». Ключевой путь - это массив индексов или ключей, который показывает, как добраться до значения, которое вы хотите обновить.
В вашем примере вы хотели обновить элемент в списке с индексом 2, а затем значение в ключе «count» в этом элементе. Так что ключевой путь будет [2, "count"]
. Второй параметр setIn
метода работает так же set
, как новое значение, которое мы хотим поместить туда, поэтому:
list = list.setIn([2, "count"], 4)
Поиск правильного ключевого пути
Сделав еще один шаг, вы на самом деле сказали, что хотите обновить элемент, имя которого - «три», что отличается от просто 3-го элемента. Например, может быть, ваш список не отсортирован, или, возможно, элемент с именем «два» был удален ранее? Это означает, что сначала нам нужно убедиться, что мы действительно знаем правильный путь ключа! Для этого мы можем использовать findIndex()
метод (который, кстати, работает почти так же, как Array # findIndex ).
Как только мы нашли индекс в списке, в котором есть элемент, который мы хотим обновить, мы можем предоставить ключевой путь к значению, которое мы хотим обновить:
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
NB: Set
vsUpdate
В исходном вопросе упоминаются методы обновления, а не установленные методы. Я объясню второй аргумент этой функции (называемой updater
), поскольку он отличается от set()
. В то время как второй аргумент set()
- это новое значение, которое мы хотим, второй аргумент update()
- это функция, которая принимает предыдущее значение и возвращает новое значение, которое мы хотим. Тогда updateIn()
это вариант «In», update()
который принимает ключевой путь.
Скажем, например, нам нужен вариант вашего примера, который не просто устанавливает счетчик 4
, но вместо этого увеличивает существующий счетчик, мы могли бы предоставить функцию, которая добавляет единицу к существующему значению:
var index = list.findIndex(item => item.name === "three")
list = list.updateIn([index, "count"], value => value + 1)