Skip to content

Collecting matches through ?:as* into a map #24

@NoahTheDuke

Description

@NoahTheDuke

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)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions