I cant understand the documentation at all.
I want a sorted map "xxx", which sorts the map according to the value. How do I do that?
Thanks.
I cant understand the documentation at all.
I want a sorted map "xxx", which sorts the map according to the value. How do I do that?
Thanks.
You use sorted-map-by by specifying a comparisson followed by the key-value-pairs. The comparator is a function which takes two keys and returns -1, 0 or 1 depending on whether the first key is smaller than, equal to or greater than the second key.
Example:
user=> (sorted-map-by (fn [k1 k2] (compare (mod k1 10) (mod k2 10))) 10 1 23 4 2 5)
{10 1, 2 5, 23 4}
Since the comparisson function only takes keys as arguments, you can't use this to sort by the values.
There is no way to have a sorted map where the map is sorted by the values. If it were, it wouldn't be possible to find an entry by key because you could not use the order to determine where the entry is (since the order would not depend on the key).
One way to achieve this is to maintain a reverse map of values to keys:
(def m (atom (sorted-map)))
(def rm (atom (sorted-map)))
(defn add
[k v]
(swap! m assoc k v)
(swap! rm assoc v (conj (get @rm v []) k)))
(add 1 "bbb")
(add 2 "ccc")
(add 3 "aaa")
(add 4 "aaa")
; @rm is now {"aaa" [3 4], "bbb" [1], "ccc" [2]}
Another way is to compare the values from the original map within the comparer function.
(def my-map {:chad 3 :bob 5 :sammy 4})
;; sort by keys ascending
(into (sorted-map) my-map)
=> {:bob 5, :chad 3, :sammy 4}
;; sort by values ascending
(into (sorted-map-by (fn [key1 key2] (compare (key1 my-map) (key2 my-map)))) my-map)
=> {:chad 3, :sammy 4, :bob 5}
;; sort by values descending
(into (sorted-map-by (fn [key1 key2] (compare (key2 my-map) (key1 my-map)))) my-map)
=> {:bob 5, :sammy 4, :chad 3}