使用幽灵的递归地图查询 [英] Recursive map query using specter

查看:94
本文介绍了使用幽灵的递归地图查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种简单的方法可以收集满足谓词的所有结构?

Is there a simple way in specter to collect all the structure satisfying a predicate ?

(./pull '[com.rpl/specter "1.0.0"])

(use 'com.rpl.specter)

(def data {:items [{:name "Washing machine"
                    :subparts [{:name "Ballast" :weight 1}
                               {:name "Hull"    :weight 2}]}]})



(reduce + (select [(walker :weight) :weight] data))
;=> 3

(select [(walker :name) :name] data)
;=> ["Washing machine"]

我们如何获取:name的所有值,包括[ Ballast Hull]?

How can we get all the value for :name, including ["Ballast" "Hull"] ?

推荐答案

这是使用递归路径停留然后继续来完成实际工作。 (如果您从 select 的path参数中省略最后一个:name ,则将获得完整的项目/部分地图,而不仅仅是:name 字符串。)

Here's one way, using recursive-path and stay-then-continue to do the real work. (If you omit the final :name from the path argument to select, you'll get the full "item / part maps" rather than just the :name strings.)

(def data
  {:items [{:name "Washing machine"
            :subparts [{:name "Ballast" :weight 1}
                       {:name "Hull" :weight 2}]}]})

(specter/select
  [(specter/recursive-path [] p
     [(specter/walker :name) (specter/stay-then-continue [:subparts p])])
   :name]
  data)
;= ["Washing machine" "Ballast" "Hull"]

更新:为回应下面的评论,以下是上述版本的降级成任意树分支的版本,与之相反只能下降到任何给定节点的:subparts 分支中,但不包括:name (这是其值在我们要提取的树,不应将其本身视为分支点):

Update: In answer to the comment below, here's a version of the above the descends into arbitrary branches of the tree, as opposed to only descending into the :subparts branch of any given node, excluding :name (which is the key whose values in the tree we want to extract and should not itself be viewed as a branching off point):

(specter/select
  [(specter/recursive-path [] p
     [(specter/walker :name)
      (specter/stay-then-continue
        [(specter/filterer #(not= :name (key %)))
         (specter/walker :name)
         p])])
   :name]
  ;; adding the key `:subparts` with the value [{:name "Foo"}]
  ;; to the "Washing machine" map to exercise the new descent strategy
  (assoc-in data [:items 0 :subparts2] [{:name "Foo"}]))

;= ["Washing machine" "Ballast" "Hull" "Foo"]

这篇关于使用幽灵的递归地图查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆