Clojure 按 id 过滤向量中的嵌套映射

Clojure filter by id the nested map in a vector

在矢量和地图数据示例中:

        [{:id 2, 
        :codigo "2", 
        :subcats 
            [{:id 3, 
              :codigo "3", 
              :subcats [], 
              :slug "pens-ss", 
              :foto nil, 
              :parent 2}
             {:id 4, 
              :codigo "44", 
              :subcats [], 
              :slug "rotula", 
              :foto nil, 
              :parent 2}
             {:id 5, 
              :codigo "hand", 
              :subcats 
                  [{:id 6, 
                      :codigo "caba", 
                      :subcats [], 
                      :slug "caballetes",
                      :foto nil, 
                      :parent 5}
                   {:id 7, 
                      :codigo "Carton", 
                      :subcats 
                           [{:id 9, 
                             :codigo "ooo", 
                             :subcats [], 
                             :slug "carton-piedra-el-nuevo", 
                             :parent 7}], 
                      :slug "cartoncillos", 
                      :foto nil, 
                      :parent 5}],
               :slug "hands", 
               :foto nil, 
               :padre 2}], 
        :slug "paper",
        :foto nil, 
        :padre nil}]

我可以过滤id的第一层,但是不能通过id过滤嵌套的"subcats"。如何在没有 "for" 的情况下过滤向量内的嵌套地图?我需要获取嵌套映射,例如,id = 5 return 所有子类别:

(filter #(= (:id %) 5 ) @cats)

通过id 5查找,我想return这个:

             {:id 5, 
              :codigo "hand", 
              :subcats 
                  [{:id 6, 
                      :codigo "caba", 
                      :subcats [], 
                      :slug "caballetes",
                      :foto nil, 
                      :parent 5}
                   {:id 7, 
                      :codigo "Carton", 
                      :subcats 
                           [{:id 9, 
                             :codigo "ooo", 
                             :subcats [], 
                             :slug "carton-piedra-el-nuevo", 
                             :parent 7}], 
                      :slug "cartoncillos", 
                      :foto nil, 
                      :parent 5}],
               :slug "hands", 
               :foto nil, 
               :padre 2}

给定根节点

(def root {:id 2, 
        :codigo "2", 
        :subcats 
            [{:id 3, 
              :codigo "3", 
              :subcats [], 
              :slug "pens-ss", 
              :foto nil, 
              :parent 2}
             {:id 4, 
              :codigo "44", 
              :subcats [], 
              :slug "rotula", 
              :foto nil, 
              :parent 2}
             {:id 5, 
              :codigo "hand", 
              :subcats 
                  [{:id 6, 
                      :codigo "caba", 
                      :subcats [], 
                      :slug "caballetes",
                      :foto nil, 
                      :parent 5}
                   {:id 7, 
                      :codigo "Carton", 
                      :subcats 
                           [{:id 9, 
                             :codigo "ooo", 
                             :subcats [], 
                             :slug "carton-piedra-el-nuevo", 
                             :parent 7}], 
                      :slug "cartoncillos", 
                      :foto nil, 
                      :parent 5}],
               :slug "hands", 
               :foto nil, 
               :padre 2}], 
        :slug "paper",
        :foto nil, 
        :padre nil})

您可以使用 tree-seq:

获得所有节点的序列
(tree-seq map? :subcats root)

然后你可以通过:id:

找到你需要的节点
(first (filter #(= 5 (:id %)) (tree-seq map? :subcats root)))

如果返回的数据是顶层的序列,您可以使用mapcat检索森林中的所有节点:

(def root [{:id 2, ...}])

(mapcat #(tree-seq map? :subcats %) root)