Как обновить только несколько ключей на карте в clojure?

У меня есть карта, на которой я хочу обновить значения (которые являются строками) но я хочу обновить только несколько ключей, а не все ключи.

Я новичок и понятия не имею, как это сделать.

Можно ли обновить только несколько ключей на карте Clojure, оставив остальные без изменений?

Как вы хотите обновить ключи? Применить к ним функцию или заменить их новыми значениями?

Lee 10.09.2018 11:42

замените их новым значением

N.Singh 14.09.2018 11:05
1
2
252
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Следующее обновит только ключи :a и :b:

(def example {:a 1 :b 2 :c 3})
(-> example
    (update :a inc)
    (update :b inc))
;; {:a 2, :b 3, :c 3}
Ответ принят как подходящий

update - правильный способ сделать это, если вы хотите применить функцию к своим значениям. в противном случае вы могли бы просто связать новые значения с картой

(def example {:a "a" :b "b" :c "c"})
(assoc example
       :a "foo"
       :c "bar")
#=> {:a "foo" :b "b" :c "bar")

или update-in для вложенных данных

(def example {:data {:a "a" :b "b" :c "c"}})
(update-in example [:data] assoc 
           :a "foo" 
           :c "bar")
#=> {:data {:a "foo" :b "b" :c "bar"}}

Эти два плюс merge и into.

Stefan Kamphausen 10.09.2018 14:08

@StefanKamphausen правда

fl00r 10.09.2018 14:48

Пытаюсь обобщить комментарии и ответы на данный момент ...

Есть несколько способов обновить только некоторые ключи на вашей карте. Какой из них лучший, зависит от

  • Ваша структура данных вложена?
    • Если они вложены, используйте assoc-in вместо assoc или update-in вместо update.
  • Вы вычисляете новые значения на основе старых?
    • Если вам нужны старые значения, используйте update и update-in вместо assoc и assoc-in.
  • Сколько у вас ключей и откуда они?
    • Все функции assoc, assoc-in, update и update-in используют скрытую рекурсию для более чем одного ключа. Со многими ключами вы можете столкнуться с исключениями переполнения стека. То же самое верно и для обозначения, использующего ->, который переписывает ваш код во вложенные вызовы.
    • В таких случаях используйте into или merge, если в противном случае вы бы использовали assoc.
    • Использование into или merge также было бы проще, если бы у вас не было фиксированного набора ключей для обновления, а было бы что-то, что вычисляется во время выполнения.
    • Обратите внимание, что into может быть быстрее, чем merge, поскольку он использует полиморфный reduce под капотом.
    • Если вы вычисляете новые значения на основе старых, то есть используете update в противном случае, рассмотрите возможность итерации по карте с использованием reduce один раз и соберите новые значения. Это более низкий уровень, но в зависимости от вашего сценария можно избежать повторения дважды.

Примеры

Пожалуйста, просмотрите (и проголосуйте за :-) другие ответы для примеров с assoc, assoc-in, update и update-in.

(def sample-map {:a 1 :b 2 :c 3})
(def new-values {:b 22 :c 33})
(into sample-map new-values)
(merge sample-map new-values)

Другие вопросы по теме