Osman
Osman

Reputation: 185

Converting a vector of maps to map of maps in Clojure

I've a vector of maps like this:

[{:categoryid 1, :categoryname "foo" } 
 {:categoryid 2, :categoryname "bar" } 
 {:categoryid 3, :categoryname "baz" }]

and would like to generate a map of maps like this for searching by categoryname

{"foo" {:categoryid 1, :categoryname "foo" }, 
 "bar" {:categoryid 2, :categoryname "bar" }, 
 "baz" {:categoryid 3, :categoryname "baz" }}

How can I do this?

Upvotes: 11

Views: 4545

Answers (4)

Eugene Pakhomov
Eugene Pakhomov

Reputation: 10632

I haven't tested it in Clojure, but in ClojureScript this variant appears to be faster than others:

(reduce #(assoc %1 (:categoryname %2) %2) {} [...])

Upvotes: 0

kotarak
kotarak

Reputation: 17299

Another way: (into {} (map (juxt :categoryname identity) [...]))

Upvotes: 16

tim_yates
tim_yates

Reputation: 171054

(ns code.groupby
  (:use clojure.contrib.seq-utils))


(def vector-of-maps [ {:categoryid 1, :categoryname "foo" }
                      {:categoryid 2, :categoryname "bar" }
                      {:categoryid 3, :categoryname "baz" } ])

(group-by :categoryname vector-of-maps)

Gives you a map of Vectors of maps

{"bar" [{:categoryid 2, :categoryname "bar"}],
 "baz" [{:categoryid 3, :categoryname "baz"}],
 "foo" [{:categoryid 1, :categoryname "foo"}]}

(which I now realise isn't what you wanted...sorry)

Upvotes: 1

Michał Marczyk
Michał Marczyk

Reputation: 84331

(reduce (fn [m {catname :categoryname :as input}]
          (assoc m catname input))
        {}
        [{:categoryid 1, :categoryname "foo" } 
         {:categoryid 2, :categoryname "bar" } 
         {:categoryid 3, :categoryname "baz" }])

Better yet,

(#(zipmap (map :categoryname %) %)
 [{:categoryid 1, :categoryname "foo" } 
  {:categoryid 2, :categoryname "bar" } 
  {:categoryid 3, :categoryname "baz" }])

Upvotes: 12

Related Questions