clojure - 尝试 'group' 并展平 clojure 中嵌套结构的值

标签 clojure

又一个不安的夜晚试图弄清楚如何做到这一点。鉴于我已重新格式化嵌套数据结构以提高可读性以查找格式错误的声明:

(def tm (list 
          {:a 1 :b 2 :c 3 :child (list 
               {:a 4 :b 5 :c 6 :child (list 
                     {:a 40 :b 50 :c 60 :child (list {:a nil :b nil :c nil})})}                                                                                               
               {:a 70 :b 80 :c 90 :child (list {:a nil :b nil :c nil})})} 
          {:a 400 :b 500 :c 600 :child (list {:a nil :b nil :c nil})}
          {:a 7 :b 8 :c 9 :child (list 
               {:a 10 :b 11 :c 12 :child (list {:a nil :b nil :c nil})})})
  )

遍历可以在下面的dg123示例中看到

我得到以下信息:

=>(roll-down tm :a)
((1 4 40) (1 70) (7 10))

但期待的是:

((1 4 40) (1 70) (400) (7 10))

最佳答案

这是一个基于 zipper 的解决方案

(require '[clojure.zip :as z])

(defn root-to-leaf-paths [t]
   (loop [t t paths []] 
     (cond 
       (z/end? t) paths
       (z/branch? t) (recur (z/next t) paths) 
       :leaf (recur (z/next t) (conj paths (z/path t))))))

(defn roll-down [d kw]
   (->> (z/zipper :child :child nil {:child d})
        (root-to-leaf-paths)
        (map (comp rest (partial map kw)))))

注意:您的 tm 不是一棵树,而是一个树列表。因此,在这里我们首先通过将树列表放置在一个父根 {:child d} 下,将此结构转换为一棵树。然后我们将其从结果路径中删除(comp rest ...)

示例

(roll-down tm :a)
;=> ((1 4 40) (1 70) (400) (7 10))

(roll-down tm :b)
;=> ((2 5 50) (2 80) (500) (8 11))

(roll-down tm :c)
;=> ((3 6 60) (3 90) (600) (9 12))

关于clojure - 尝试 'group' 并展平 clojure 中嵌套结构的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21505805/

相关文章:

clojure - Clojure 和 Clojurescript 的接口(interface)

hadoop - 为什么 Spark 运行多个进程?

clojure - 在 Clojure 中是否有更好的方法来访问嵌套映射和向量?

Clojure 打印功能 : pr vs print

math - Clojure 中的基本几何

for-loop - :while and :when in clojure? 和有什么区别

clojure.core : . 运算符、defmacro 和 setMacro

clojure - 在 clojure 代码中查找不匹配(错误匹配)的括号/更有意义的错误消息

Clojure命名空间: method to see defined objects?

clojure - Clojure REPL 到底是什么?它背后的技术是什么?