使用幽灵的递归地图查询 [英] Recursive map query using specter
问题描述
是否有一种简单的方法可以收集满足谓词的所有结构?
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"] ?
推荐答案
这是使用递归路径$ c $的一种方法c>和
停留然后继续
来完成实际工作。 (如果您从 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屋!