Recursion Clojure-递归展平嵌套映射

Recursion Clojure-递归展平嵌套映射,recursion,clojure,Recursion,Clojure,给定一个带有键:content的映射,其中content是字符串或其他映射的列表,如何将值展平以仅接收字符串 (flattener {:content '("b" {:content ("c" {:content ("d")})} "e")}) > '("b" "c" "d" "e") 我正跌跌撞撞地经历着一次又一次的恶性循环,现在我的大脑被烧坏了。在Clojure中有没有一种很好的惯用方法 谢谢 我得到的是下面的,虽然它有效,但它相当丑陋 (defn flatten-content

给定一个带有键: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)))))

tree-seq
功能有助于行走,并在地图上显示

(def m {:content '("b" {:content ("c" {:content ("d")})} "e")})
总是有一个由
:content
键控的“子项”列表,这很有效

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

下面的递归函数可以工作(比
过滤器
ed
树序列
方法快约25%:


很难在优雅方面击败它。谢谢
(defn flatten-content [node]
  (lazy-seq
    (if (string? node)
      (list node)
      (mapcat flatten-content (:content node)))))