let's say I want to collect lists of matching patterns and also a map key at a higher level in a nested map. ie. given the following map:
{:a {:client "foo"
:items [{:x 1} 2 3]}
:b {:client "bar"
:items [{:x "q"} {:x "x"}]}}
I'd like to collect all values of maps with key :x under :items and also the value of :client that appears alongside those :items:
[["foo" [1] ["bar" ["q" "x"]]
What's a good way of doing this? Is it possible to generate that output with meander alone?I can get pretty close with the following:
(m/search {:a {:client "foo"
:items [{:x 1} 2 3]}
:b {:client "bar"
:items [{:x "q"} {:x "x"}]}
}
(m/$ {:client ?c
:items (m/scan {:x !i})})
[?c !i])
but it gives me pairs for each match rather than aggregating the !i values:
(["foo" [1]] ["bar" ["q"]] ["bar" ["x"]])
(For more context, the map above is a simplified one; the actual map I want to extract the data from has a lot more levels of nesting under :items before the :x keys appear)
(defn f [m]
(m/find m
{:client ?client
:items [(m/or {:x !x} _) ...]}
[?client !x]))
(m/search {:a {:client "bar"
:items [{:x "q"} {:x "x"}]}
:b {:client "foo"
:items [{:x 1} 2 3]}}
{_ {:as ?v}} (f ?v))
;; =>
(["bar" ["q" "x"]] ["foo" [1]])This would all be one pattern if epsilon had proper greediness.
Gotcha - thanks for the context! I'll keep this in mind when I write queries in the future. The output without proper greediness is still very useful to me because it simplifies a lot of the map traversal logic that I'd otherwise have to write