Clojure - 递归展平嵌套地图

时间:2014-11-29 23:06:20

标签: recursion clojure

给定一个带有键的地图:content,其中content是字符串列表或其他地图,如何将值展平以仅接收字符串?

(flattener {:content '("b" {:content ("c" {:content ("d")})} "e")})

> '("b" "c" "d" "e")

我经历了非常骇人的循环复发尝试,现在我的大脑被烧毁了。在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)))))

2 个答案:

答案 0 :(得分:8)

tree-seq功能有助于步行,并且自地图

(def m {:content '("b" {:content ("c" {:content ("d")})} "e")})

总是有一个由:content键入的“孩子”列表,这可行

(filter string? (tree-seq associative? :content m))
;=> ("b" "c" "d" "e")

答案 1 :(得分:5)

以下递归函数有效(并且比filter ed tree-seq方法快约25%):

(defn flatten-content [node]
  (lazy-seq
    (if (string? node)
      (list node)
      (mapcat flatten-content (:content node)))))