2014-10-23 3 views
2

Что такое идиоматический способ сочетания нового значения с вектором, который находится на карте в атоме?Обновление свойства Clojure atom

Ближайший я смог прийти следующий:

(def blog (atom {:posts []})) 

(swap! 
    blog 
    (fn [current] 
     {:posts (conj (:posts current) {:title "War of Worlds"})})) 

Какие результаты в:

{:posts [:title "War of Worlds"]} 

Использование лямбда чувствует излишне многословным.

+1

'update-in' - ваш друг. –

+3

(swap! Blog # (update-in% [: posts] conj {: title "War of the Worlds"})) – galdre

+1

... что ваш исходный код _does not_ фактически предотвращает ': posts' от оставшегося вектор. Вы можете легко проверить, что '(conj []: foo)' возвращает '[: foo]', так же как '(conj (list): foo)' returns ''(: foo)'. –

ответ

7

Я хотел бы сделать:

(swap! blog update-in [:posts] conj {:title "War of the Worlds"}) 

Оба подкачки! и обновить в соответствии с формой «модель обновления», и они могут быть с прибылью объединены вместе. Это очень распространенный шаблон, особенно с обновлением контейнера с установленными состояниями и вложенными картами.

«Обновить модель» означает функции вида: (defn u [context f & args]), вызываемые как (apply f context args).

+0

Это именно то, что я предвидел. Благодаря! – pdoherty926

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