Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reversing hash map in clojure

I've hash-map in clojure:

{"key1" "value1"} {"key2" "value2"} {"key3" "value1"}

and i need to convert it into hash map of

{"value1" {"key1" "key3"}} {"value2" {"key2"}}

Any clojure way of doing this?

clojure.set/map-invert will not work as if it overrides repeated values.

like image 710
ts. Avatar asked Aug 13 '26 02:08

ts.


2 Answers

(def m {"key1" "value1" "key2" "value2" "key3" "value1"})

(let [g (group-by val m)
      vals (map #(map first %) (vals g))]
  (zipmap (keys g) vals))
;;=> {"value2" ("key2"), "value1" ("key1" "key3")}
like image 174
Michiel Borkent Avatar answered Aug 16 '26 13:08

Michiel Borkent


Give this a try:

(def m {"key1" "value1" "key2" "value2" "key3" "value1"})

(reduce (fn [a x] (assoc a (second x) (conj (a (second x)) (first x)))) {} m)
=> {"value2" ("key2"), "value1" ("key3" "key1")}

Notice that the (possibly) repeated values end up in a list. Or, as suggested by @A.Webb in the comments, the above can be concisely written like this:

(reduce (fn [a [k v]] (update-in a [v] conj k)) {} m)
=> {"value2" ("key2"), "value1" ("key3" "key1")}
like image 21
Óscar López Avatar answered Aug 16 '26 14:08

Óscar López



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!