Returns the map with the vals mapped to the keys.
;; Despite being in clojure.set, this has nothing to do with sets. user=> (map-invert {:a 1, :b 2}) {2 :b, 1 :a} ;; If there are duplicate keys, one is chosen: user=> (map-invert {:a 1, :b 1}) {1 :b} ;; I suspect it'd be unwise to depend on which key survives the clash.
;; The inverted map of an empty map is also an empty map. user=> (map-invert {}) {} ;; Using complex values (which serve as keys in the inverted map) is possible. user=> ((map-invert {:a {:c 5}}) {:c 5}) :a
;; simple text obfuscation and back, with map-invert (def scramble-key {\a \t \b \m \c \o \d \l \e \z \f \i \g \b \h \u \i \h \j \n \k \s \l \r \m \a \n \q \o \d \p \e \q \k \r \y \s \f \t \c \u \p \v \w \w \x \x \j \y \g \z \v \space \space}) (defn scramble [text scramble-key] (apply str (map scramble-key text))) (defn unscramble [text scramble-key] (apply str (map (map-invert scramble-key) text))) (scramble "try to read this if you can" scramble-key) ;; "cyg cd yztl cuhf hi gdp otq" (unscramble "cyg cd yztl cuhf hi gdp otq" scramble-key) ;; "try to read this if you can"
clojure.set/map-invert
If you have the possibility of duplicate values, in your map, the invert-map function will only preserve one of them. An alternative which doesn't eliminate values is to ensure all values are sets then use the following function:
(defn invert-map-of-sets [m] (reduce (fn [a [k v]] (assoc a k (conj (get a k #{}) v))) {} (for [[k s] m v s] [v k]))))This will work as follows:
;; From {1 #{:a :b :c} 2 #{:b :c :d}}
;; To {:c #{1 2}, :b #{1 2}, :a #{1}, :d #{2}}