2016-02-19 6 views
3

У меня есть эта карта Clojure: добавить элемент в вектор Iside карте

(def m {:a "aaa" :b {:c ["ss" "gg"]}}) 

Я хочу, чтобы обновить его до этого (добавить «уу» к вектору: с):

{:a "aaa" :b {:c ["ss" "gg" "uu"]}} 

Это то, что я придумал, и я ненавижу:

(assoc-in m [:b :c] (conj (get-in m [:b :c]) "uu")) 

Как должен я быть Делать это?

ответ

5
(update-in m [:b :c] conj "uu") 

Как я думаю об этом, что update-inполучает вас там и вызывает функцию, которая принимает состояние, которое там. Эта функция (conj здесь) также принимает остальные параметры. Итак, здесь conj будет вызываться с ["ss" "gg"] и "uu".

assoc-in не получает никакого начального состояния, поэтому в вашем примере вам нужно работать, чтобы создать то, что есть сначала.

+0

Это именно то, что я искал, спасибо! – siltalau

+4

, но остерегайтесь ловушки: если ключ отсутствует на карте, 'conj' создаст список, а не вектор:' (update-in m [: b: d] conj "xxx") '=>' { : a "aaa",: b {: c ["ss" "gg"],: d ("xxx")}} '. Чтобы избежать этого, вы должны обрабатывать значения «nil», например: '(update-in m [: b: d] (fnil conj [])" xxx ")' => '{: a" aaa ",: b {: c ["ss" "gg"],: d ["xxx"]}} ' – leetwinski

Смежные вопросы