Fork me on GitHub
#meander
<
2020-02-26
>
maxt17:02:29

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

jimmy18:02:29

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.

jimmy18:02:33

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

maxt18:02:48

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.

😆 4
jimmy18:02:25

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

maxt18:02:28

(m/match [{:name "Alice" :id 1}
          {:name "Bob" :id 2}]
         [{:name !names :id !ids} ...]
         (zipmap !names !ids))

👍 4
maxt18:02:43

yet another version