How to change the display order of a map in Clojure?

I have an ordered map, for example:

{:a 1 :b 2 :c 3} 

: and a list of orderings of the type:

 [:c :a] 

: I would like to find the easiest way to get:

 {c: 3 :a 1} 

: Does anyone know how to do this?

Update:

 (defn asort [amap order] (conj {} (select-keys amap order))) (asort {:a 1 :b 2 :c 3} [:c :a] ) 
+6
clojure
source share
2 answers

I would probably convert the ordering vector to a hash map to quickly find the ordering index, resulting in something like this:

 { :c 0 :a 1 } 

There are several ways to do this automatically from seq / vector (for example, map with range and then reduce to {} with assoc ). Bind the result of this (or the literal map above) to the local one (with let ), call it order-map .

Then filter the source map entries (m) to include only those that are included in the order:

 (select-keys m order) 

And put the result of this filtered expression back onto the new sorted map (using sorted-map-by ) using a comparator function such as:

 (fn [ab] (compare (order-map a) (order-map b))) 

Please note: if you really do not need it as a map, and the sequence is completed, you can use sort-by with a key function that uses the same order map.

Combining this, you get:

 (defn asort [m order] (let [order-map (apply hash-map (interleave order (range)))] (conj (sorted-map-by #(compare (order-map %1) (order-map %2))) ; empty map with the desired ordering (select-keys m order)))) 

and

 => (asort (apply sorted-map (interleave (range 0 50) (range 0 50))) (range 32 0 -1)) {32 32, 31 31, 30 30, 29 29, 28 28, 27 27, 26 26, 25 25, 24 24, 23 23, 22 22, 21 21, 20 20, 19 19, 18 18, 17 17, 16 16, 15 15, 14 14, 13 13, 12 12, 11 11, 10 10, 9 9, 8 8, 7 7, 6 6, 5 5, 4 4, 3 3, 2 2, 1 1} 
+9
source share

Here is an easy way to do this:

 (defn asort [amap order] (conj {} (select-keys amap order))) 

as a result of:

 clojure.core> (asort {:a 1 :b 2 :c 3} [:c :a]) {:c 3, :a 1} clojure.core> (asort {:a 1 :b 2 :c 3} [:a :c]) {:a 1, :c 3} 

Update : as written in the comments, this solution only works for small cards (see HASHTABLE_TRESHOLD ), ultimately relying on hidden details of the implementation of basic data structures. The accepted answer is correct.

+1
source share

All Articles