Looking at the example:
(into [] (select-keys {:a 1 :b 2 :c 3} [:c :b])) => [[:c 3] [:b 2]]
Is it guaranteed that returned result will preserve order declared in second parameter of select-key
?
select-keys
returns a map which are unorderd, so you can't rely on it. Small maps are represented as arrays which do maintain order but this is broken as the size increases eg
(def m {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9 :j 10 :k 11 :l 12 :m 13})
(into [] (select-keys m [:a :b :c :d :e :f :g :h :i :j :k]))
=> [[:e 5] [:k 11] [:g 7] [:c 3] [:j 10] [:h 8] [:b 2] [:d 4] [:f 6] [:i 9] [:a 1]]
It's not a reliable function to preserve orders, as well as keys
and vals
which do not preserve the order of how you defined the map. The most reliable way is to use a loop
/ recur
if you want to output an ordered vector of kv (or a reduce
as well). If you want ordered values only, you can use juxt
.
I would add that pragmatically hashmaps are not meant to represent ordered data.
If the ordering is a fairly simple one, you can easily sort the map by using sorted-map-by
:
(def m (select-keys {:a 1 :b 2 :c 3 :d 4} [:d :b]))
=> {:d 4, :b 2}
(def sm (sorted-map-by compare))
(into sm m)
=> {:b 2, :d 4}
(assoc *1 :c 1234)
=> {:b 2, :c 1234, :d 4} ; maintains sort when additional kvs are assoc'd
(into [] *1)
=> [[:b 2] [:c 1234] [:d 4]]
Even if the ordering is not simple, you can write a custom comparator. This is rife with pitfalls, but there is a guide that is very good. It's not what you were originally after, but it's relevant.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.