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}