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);
Теперь, если мы хотим, чтобы обновить 3-й пункт, простой массив JS может выглядеть следующим образом: counts[2] = 4
. Поскольку мы не можем использовать мутацию и нужно вызвать метод, вместо этого мы можем использовать: counts.set(2, 4)
- это означает, что значение 4
по индексу 2
.
Глубокие обновления
В примере вы дали имеет вложенные данные, хотя. Мы не можем просто использовать set()
в первоначальной коллекции.
В коллекциях Immutable.js есть семейство методов с именами, заканчивающимися на «In», которые позволяют вам делать более глубокие изменения во вложенном наборе. Наиболее распространенные методы обновления имеют связанный метод «В». Например, для set
есть setIn
. Вместо того, чтобы принимать индекс или ключ в качестве первого аргумента, эти методы «В» принимают «ключевой путь». Ключевым путем является массив индексов или ключей, который иллюстрирует, как получить значение, которое вы хотите обновить.
В вашем примере вы хотели обновить элемент в списке по индексу 2, а затем значение в ключе «счет» внутри этого элемента. Таким образом, ключевой путь будет [2, "count"]
. Второй параметр метода setIn
работает точно так же, как set
, это новое значение, которое мы хотим поставить там, так:
list = list.setIn([2, "count"], 4)
найти правильный ключ путь
Going один шаг дальше, вы на самом деле сказал вы хотели обновить элемент, где имя «три», которое отличается от третьего. Например, возможно, ваш список не отсортирован, или, возможно, элемент с именем «два» был удален ранее? Это означает, что сначала нам нужно убедиться, что мы действительно знаем правильный путь ключа! Для этого мы можем использовать метод findIndex()
(который, кстати, работает почти точно как Array#findIndex).
После того, как мы обнаружили, индекс в списке, который имеет элемент, который мы хотим обновить, мы можем обеспечить ключ путь к значению мы хотим обновить:
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
NB: Set
против Update
В исходном вопросе упоминаются методы обновления, а не установленные методы. Я объясню второй аргумент в этой функции (так называемый updater
), так как он отличается от set()
. Хотя второй аргумент set()
- это новое значение, которое мы хотим, второй аргумент update()
- это функция , которая принимает предыдущее значение и возвращает новое значение, которое мы хотим. Затем updateIn()
является вариацией «В» update()
, которая принимает ключевой путь.
Скажем, например, мы хотели вариацию вашего примера, который не только установить счетчик на 4
, но вместо этого увеличивается существующий счет, мы могли бы обеспечить функцию, которая добавляет один к существующему значению:
var index = list.findIndex(item => item.name === "three")
list = list.updateIn([index, "count"], value => value + 1)
Похоже на машинопись для меня ... – Bergi
Я не знаю, как это выглядит, но документация ужасна http://facebook.github.io/immutable-js/docs/#/List/update –
Серьезная поддержка для в документации. Если цель этого синтаксиса - заставить меня чувствовать себя немым/неадекватным, определенным успехом. Если цель, однако, состоит в том, чтобы сообщить, как работает Immutable, хорошо ... – Owen