-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Hey hey,
I've been playing around with this library as my own pattern library isn't nearly as powerful, and I'm interested to know if this behavior is possible or would be considered:
I am matching against hiccup, specifically a [:table ...] element that can have an arbitrary number of :tr rows in the :tbody. I'm collecting these rows using this pattern:
(def csp-canoe-sprint
(compile-pattern
'[:table (? _ map?)
[:thead (?:* (? head))]
[:tbody
(? _ map?)
(?:as* rows
(?:*
[:tr (? _ map?)
[:td (? _ map?) (? position parse-pos)]
(?? _)
[:td (? _ map?) [:a (?? _) (? winner string?)]]
(?? _)
[:td (? _ map?) [:a (?? _) (? NOC country-code->name)]]
(?? _)
[:td (? _ map?) [:span (? _ map?) (? medal #{"Gold" "Silver" "Bronze"})]]
(?? _)]))]]))When it matches, it results in a map with :head, :rows, :position, :winner, :NOC, and :medal. Each of the :rows is the whole matched [:tr ...] object, and the :position etc entries are vectors of the matches: ["Noah" "Santa"]. I'd like for there to be some way to "collect" the nested matches into individual maps, like rows of a csv: {:rows [{:position "1" :winner "Noah" :NOC "USA" :medal "Gold"} {:position "2" :winner "Santa" :NOC "North Pole" :medal "Silver"}]}.
Is this possible? If not, do you have ideas how I could achieve this?
EDIT: I know I could do this mapping myself because the match will only happen when each row is matched, so the length of position, winner, NOC, and medal will all be equal, but that requires manually constructing the maps for every pattern I write, which will be... arduous (I plan on having upwards of 100 patterns lol).
(let [match (csp-canoe-sprint table)]
(mapv (fn [p w n m] {:position p :winner w :NOC n :medal m})
(:position match)
(:winner match)
(:NOC match)
(:medal match)))