Hi! Is there a good way to get from
[{:name "Alice" :id 1}
{:name "Bob" :id 2}]
to
{1 "Alice"
2 "Bob"}
?
Match doesn't let me scan and search returns two maps
(m/search [{:name "Alice" :id 1}
{:name "Bob" :id 2}]
(m/scan {:name ?name :id ?id})
{?name ?id})
With rewrite you can do the following:
(m/rewrite [{:name "Alice" :id 1}
{:name "Bob" :id 2}]
[{:name !names :id !ids} ...]
{& [[!names !ids] ...]})
I should probably put this example in the cookbook. Sadly with maps ...
isn't straight forward. But the {& [[x y] ...]}
is a nice little idiom for building up maps.
Also, just to mention the alternative possibility, if you really needed search you could use into.
(into
{}
(m/search [{:name "Alice" :id 1}
{:name "Bob" :id 2}]
(m/scan {:name ?name :id ?id})
{?name ?id}))
My recommendation is trying out rewrite for this.Just throw more ways out. You can do this with match and some pretty standard clojure.
(m/match [{:name "Alice" :id 1}
{:name "Bob" :id 2}]
[{:name !names :id !ids} ...]
(into {} (map vector !ids !names)))
Thanks a lot for the rewrite suggestion, I wouldn't have come up with that one myself 🙂 It's of course easy to convert it with into, but how fun is that? Seriously it does loose some of the what you see is what you get-ness.
Yeah, and the &
solution for maps isn't the most wysiwyg thing either. Sadly we couldn't think of a great way to do repeats since maps have to always have pairs and are un-ordered.
A perennial topic that comes up is adding a map-of operator. But we've yet to settle on an implementation. https://github.com/noprompt/meander/issues/74
(m/match [{:name "Alice" :id 1}
{:name "Bob" :id 2}]
[{:name !names :id !ids} ...]
(zipmap !names !ids))
yet another version