Как nberger делает, мы выделим перечисляющем пути от представления их как строки.
Перечень
Функция
(defn paths [x]
(if (map? x)
(mapcat (fn [[k v]] (map #(cons k %) (paths v))) x)
[[x]]))
... возвращает последовательность пути-последовательностей вложенной карте. Например,
(paths {"foo" {"bar" "1", "baz" "2"}})
;(("foo" "bar" "1") ("foo" "baz" "2"))
Презентация
Функция
#(clojure.string/join \/ %)
... соединяет строки вместе с "/" с. Например,
(#(clojure.string/join \/ %) (list "foo" "bar" "1"))
;"foo/bar/1"
компоновать, чтобы получить нужную вам функцию:
(def traverse (comp (partial map #(clojure.string/join \/ %)) paths))
...или просто
(defn traverse [x]
(->> x
paths
(map #(clojure.string/join \/ %))))
Например,
(traverse {"foo" {"bar" "1", "baz" "2"}})
;("foo/bar/1" "foo/baz/2")
- Вы можете вплетать их в качестве одной функции: более четкой и полезной для разделить их, я думаю.
- Перечисление не является ленивым, поэтому он будет исчерпан пространство стека на достаточно глубоко вложенных картах.
Почему нет молнии? – RedDeckWins
Я пытаюсь обернуть мою голову вокруг рекурсивной глубины первого обхода в clojure, и мне любопытно, являются ли молнии единственным способом выполнить эту задачу? – Upgradingdave