Fork me on GitHub
#specter
<
2020-07-27
>
Vincent Cantin12:07:15

Hi. I am trying to collect all values which are associated to a keyword :tags in a hierarchy of maps. Is there an easy way to do that using Specter?

Vincent Cantin13:07:59

I tried this, but it does not walk into maps which have :tags:

(s/select [(s/walker #(and (map? %) (contains? % :tags))) :tags s/ALL]
          {:a {:tags [1 {:tags [2]}]}
           :b {:tags [3]}})
; => [1 {:tags [2]} 3]

nathanmarz18:07:22

@vincent.cantin easy to do with recursive-path

user=> (def data
  #_=>   {:a {:tags [1 {:tags [2]}]}
  #_=>    :b {:tags [3]}})
#'user/data
user=> 

user=> (def MY-WALKER
  #_=>   (recursive-path [] p
  #_=>     (continue-then-stay
  #_=>       (cond-path map? MAP-VALS
  #_=>                  sequential? ALL)
  #_=>       p
  #_=>       )))
#'user/MY-WALKER
user=> 

user=> (select [MY-WALKER map? (must :tags) ALL] data)
[2 1 {:tags [2]} 3]