【问题标题】:Clojure - Recursively Flatten Nested MapsClojure - 递归展平嵌套地图
【发布时间】:2015-01-28 06:17:41
【问题描述】:

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

【问题讨论】:

    标签: recursion clojure


    【解决方案1】:

    tree-seq 函数有助于走路,因为你的地图

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

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

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

    【讨论】:

    • 在优雅方面很难击败它。谢谢。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 2020-02-14
      • 2021-06-01
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      相关资源
      最近更新 更多