2015-03-10 2 views
1

У меня есть динамически созданная структура данных карты, которая позже будет разобрана в JSON. Поэтому уровни вложенности и т. Д. Неизвестны и зависят от данных.Clojure: поиск/замена значений в динамической вложенной карте/seq

Если ключ имеет несколько значений, они представляются в виде карт внутри последовательности.

Вот пример:

{:key "value" 
:anotherKey "anotherValue" 
:foo "test" 
:others [ {:foo "test2"} {:foo "test3"} ] 
:deeper {:nesting {:foo "test4"} } 
} 

теперь я хочу, чтобы искать ключ :foo и добавьте "/bar" к значению.

Результат должен вернуть модифицированную карту:

{:key "value" 
:anotherKey "anotherValue" 
:foo "test/bar" 
:others [ {:foo "test2/bar"} {:foo "test3/bar"} ] 
:deeper {:nesting {:foo "test4/bar"} } 
} 

Что бы чистый и простой способ для достижения этой цели?

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

+0

Какой результат для вас ожидать? Значение для * каждого * ': foo', добавленного или только первого уровня? – Thumbnail

+0

спасибо, я отредактировал вопрос в соответствии: результатом должна быть измененная карта. – echox

+0

Пожалуйста, покажите нам * измененную карту *. – Thumbnail

ответ

9

Там может быть что-то проще, чем это:

(clojure.walk/prewalk 
    (fn [m] 
    (if (and (map? m) (:foo m)) 
     (update-in m [:foo] #(str % "/bar")) 
     m)) 
    {:key "value" 
    :anotherKey "anotherValue" 
    :foo "test" 
    :others [{:foo "test2"} {:foo "test3"}] 
    :deeper {:nesting {:foo "test4"}}}) 

=> 
{:anotherKey "anotherValue", 
:key "value", 
:deeper {:nesting {:foo "test4/bar"}}, 
:foo "test/bar", 
:others [{:foo "test2/bar"} {:foo "test3/bar"}]} 
+0

спасибо, что превью и обновление - отлично работают вместе – echox