Обновите значения нескольких ключей - PullRequest
14 голосов
/ 09 марта 2012

Если у вас есть карта или коллекция карт, и вы хотите иметь возможность обновлять значения нескольких клавиш с помощью одной функции, какой самый идиоматичный способ сделать это?

=> (def m [{:a 2 :b 3} {:a 2 :b 5}])
#'user/m
=> (map #(update-in % [:a] inc) m)
({:a 3, :b 3} {:a 3, :b 5})

Вместо того, чтобы отображать обновление для каждой клавиши, в идеале я хотел бы, чтобы какая-то функция работала так:

=> (map #(update-vals % [:a :b] inc) m)
({:a 3, :b 4} {:a 3, :b 6})

Любой совет будет высоко ценится!Я пытаюсь уменьшить количество строк в излишне длинном скрипте.

1 Ответ

24 голосов
/ 09 марта 2012

Всякий раз, когда вам нужно итеративно применить fn к некоторым данным, reduce ваш друг:

(defn update-vals [map vals f]
  (reduce #(update-in % [%2] f) map vals))

Вот оно в действии:

user> (def m1 {:a 2 :b 3})
#'user/m1
user> (update-vals m1 [:a :b] inc)
{:a 3, :b 4}
user> (def m [{:a 2 :b 3} {:a 2 :b 5}])
#'user/m
user> (map #(update-vals % [:a :b] inc) m)
({:a 3, :b 4} {:a 3, :b 6})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...