给定一个带有键的映射:content,其中content是字符串列表或其他映射,如何将值展平以仅接收字符串?
(flattener {:content '("b" {:content ("c" {:content ("d")})} "e")})
> '("b" "c" "d" "e")
Run Code Online (Sandbox Code Playgroud)
我正在磕磕绊绊地进行非常粗暴的循环重复尝试,现在我的大脑被烧毁了.在Clojure中有一个很好的惯用方法吗?
谢谢.
我得到的是下面的,虽然它有效,但它很难看
(defn flatten-content
[coll]
(loop [acc '(), l coll]
(let [fst (first l), rst (rest l)]
(cond
(empty? l) (reverse acc)
(seq? fst) (recur acc (concat fst rst))
(associative? fst) (recur acc (concat (:content fst) rst))
:else (recur (conj acc fst) rst)))))
Run Code Online (Sandbox Code Playgroud)
该tree-seq功能有助于步行,并且因为您的地图
(def m {:content '("b" {:content ("c" {:content ("d")})} "e")})
Run Code Online (Sandbox Code Playgroud)
总是有一个"儿童"列表:content,这是有效的
(filter string? (tree-seq associative? :content m))
;=> ("b" "c" "d" "e")
Run Code Online (Sandbox Code Playgroud)
以下递归函数有效(并且比filtered tree-seq方法快约25%):
(defn flatten-content [node]
(lazy-seq
(if (string? node)
(list node)
(mapcat flatten-content (:content node)))))
Run Code Online (Sandbox Code Playgroud)