如何在深层嵌套的数据结构中查找元素?

时间:2015-08-19 18:54:29

标签: clojure tree-traversal

我有这个结构(它是解析JSON响应的结果):

 [{"a" {"b" 1 "c" 2} 
       "children" [{"a" {"b" 3 "c" 4} "children" []}]}
  {"a" {"b" 5 "c" 6} "children" []}
  {"a" {"b" 7 "c" 8}
        "children" [{"a" {"b" 9 "c" 10} "children" []}]}]

所以它是一棵树。 children是节点的向量。每个节点都是a, b and children

的地图

我试图找到其9属性值为b的节点。 因此,查找的结果是:

我试图用tree-seq遍历结构:

(tree-seq #(not-empty? % "children") identity structure)

但实际上我得到了相同的结构。我期望获得一系列节点,其中关系被展平,然后我可以对序列进行过滤。

如何以惯用的方式做到这一点(并希望表现得很好)?随意用拉链或走路来打扰我。

2 个答案:

答案 0 :(得分:2)

您可以像这样获得所需的tree-seq:

(def ts (mapcat (partial tree-seq #(contains? % "children") 
                                  #(get % "children"))
                your-data-structure))

mapcat是必需的,因为您的输入数据结构包含多个根节点。

电子。 G。找到一个像这样的节点:

(first (filter #(= (get-in % ["a" "b"]) 9) ts))
;-> {"a" {"b" 9, "c" 10}, "children" []}

答案 1 :(得分:0)

(def data
  [{"a" {"b" 1 "c" 2} 
    "children" [{"a" {"b" 3 "c" 4} "children" []}]}
   {"a" {"b" 5 "c" 6} 
    "children" []}
   {"a" {"b" 7 "c" 8}
    "children" [{"a" {"b" 9 "c" 10} "children" []}]}])

branch? fn将在第一次迭代时接收整个向量作为参数,因此我使用vector?谓词,但这是不必要的,因为我们可以使用简单的not-empty函数简化它矢量和地图都很好。

(tree-seq 
  not-empty
  #(if (vector? %) % (% "children")) 
  data)