mwal
mwal

Reputation: 3103

"flatten" a list of maps to a single map in clojure?

I want to go from this list of maps, returned by a jdbc query:

'({:series_id 1 :expires_at "t1"} {:series_id 2 :expires_at "t2"})

to a single map like:

{1 "t1" 2 "t2"}

That's so I can look up expires_at using simply the series_id integer.

I've got as far as:

db.core=> (mapcat #((comp vals select-keys) %1 [:series_id :expires_at]) 
                  '({:series_id 1, :expires_at "t1"} {:series_id 2 :expires_at "t2"}))
(1 "t1" 2 "t2")

but that's a list, not a map.

I wonder if this is a candidate for reduce, and/or if there are some other neat ways to do it.

Upvotes: 3

Views: 476

Answers (2)

Riley
Riley

Reputation: 1071

Alternately, with a list comprehension and destructuring

(defn flatten-expiration-data [the-maps]
 (into {}
  (for [{id :series_id expiration :expires_at} the-maps]
    [id expiration])))

It's more verbose than @Lee's answer, but I hope it also helps readers learn the language!

Upvotes: 3

Lee
Lee

Reputation: 144126

You can convert each map into a pair of [series_id expires_at] and then convert the corresponding sequences of pairs into a map:

(def l '({:series_id 1 :expires_at "t1"} {:series_id 2 :expires_at "t2"}))
(into {} (map (juxt :series_id :expires_at) l))

Upvotes: 8

Related Questions