Вот что сказали официальные документы
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>
Нормальный веб-разработчик (не функциональный программист) не может этого понять!
У меня довольно простой (для нефункционального подхода) случай.
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
где элемент с именем третьего иметь счета набор на 4 ?
javascript
functional-programming
immutable.js
Виталий Корсаков
источник
источник
Ответы:
Наиболее подходящий случай использовать как
findIndex
иupdate
методу.PS Не всегда можно использовать Карты. Например, если имена не уникальны, и я хочу обновить все элементы с одинаковыми именами.
источник
С .setIn () вы можете сделать то же самое:
Если мы не знаем индекс записи, которую хотим обновить. Найти его довольно просто с помощью .findIndex () :
Надеюсь, поможет!
источник
{ }
внутриfromJS( )
, без фигурных скобок это недействительный JS.объяснение
Обновление коллекций Immutable.js всегда возвращает новые версии этих коллекций, оставляя исходную неизменной. Из-за этого мы не можем использовать
list[2].count = 4
синтаксис мутации JavaScript . Вместо этого нам нужно вызывать методы, как и в случае с классами коллекций Java.Начнем с более простого примера: просто счетчики в списке.
Теперь , если мы хотим , чтобы обновить 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
, как новое значение, которое мы хотим поместить туда, поэтому:Поиск правильного ключевого пути
Сделав еще один шаг, вы на самом деле сказали, что хотите обновить элемент, имя которого - «три», что отличается от просто 3-го элемента. Например, может быть, ваш список не отсортирован, или, возможно, элемент с именем «два» был удален ранее? Это означает, что сначала нам нужно убедиться, что мы действительно знаем правильный путь ключа! Для этого мы можем использовать
findIndex()
метод (который, кстати, работает почти так же, как Array # findIndex ).Как только мы нашли индекс в списке, в котором есть элемент, который мы хотим обновить, мы можем предоставить ключевой путь к значению, которое мы хотим обновить:
NB:
Set
vsUpdate
В исходном вопросе упоминаются методы обновления, а не установленные методы. Я объясню второй аргумент этой функции (называемой
updater
), поскольку он отличается отset()
. В то время как второй аргументset()
- это новое значение, которое мы хотим, второй аргументupdate()
- это функция, которая принимает предыдущее значение и возвращает новое значение, которое мы хотим. ТогдаupdateIn()
это вариант «In»,update()
который принимает ключевой путь.Скажем, например, нам нужен вариант вашего примера, который не просто устанавливает счетчик
4
, но вместо этого увеличивает существующий счетчик, мы могли бы предоставить функцию, которая добавляет единицу к существующему значению:источник
Вам не нужно
updateIn
, это только для вложенных структур. Вы ищетеupdate
метод с гораздо более простой подписью и документацией:что, как предполагается в
Map::update
документации , " эквивалентно:list.set(index, updater(list.get(index, notSetValue)))
".Списки работают не так. Вы должны знать индекс элемента, который хотите обновить, или вам нужно искать его.
Это должно сделать это:
источник
Map
какойList
подход вы бы предложили? Или вы говорите это только потому, что OP сказал «выбрать элемент по имени», а не «выбрать элемент по идентификатору»?Используйте .map ()
источник
Мне очень нравится этот подход с сайта thomastuts :
источник
Вы можете использовать
map
:Но это будет повторяться по всей коллекции.
источник