在clojure中将map转换为vector时,结果的顺序是否相同?

时间:2015-01-10 12:41:03

标签: clojure

我正在使用键和val在地图上工作,如果我多次运行相同的代码,它是否总是会考虑订单返回相同的集合?我每次运行时都试过(键a)(:c:b:a)  回报。但是要确认它总是返回相同的。

(def a {:a 1 :b 2 :c 3})
(keys a)
(vals a)

2 个答案:

答案 0 :(得分:3)

并非所有Clojure地图都会保留条目顺序。如果要保留插入顺序,则需要使用clojure.lang.PersistentArrayMap(由array-map生成或地图文字)。请记住,数组映射适用于少量条目,并且某些操作在较大数量的条目下性能较差。

如果您想维护排序顺序(但不是插入顺序),那么您需要使用有序地图(由sorted-map生成)。

哈希映射(由hash-map生成)不提供有关订单的保证。

Clojure的地图文字产生一个数组地图。

(class {:a 1 :b 2 :c 3})
; => clojure.lang.PersistentArrayMap

; zipmap's returned map type will vary depending on the number of entries in the map 
(class (zipmap (range 0 1000) (range 1000 2000)))
; => clojure.lang.PersistentHashMap

(class (zipmap (range 1 3) (range 3 5)))
; => clojure.lang.PersistentArrayMap

(class (sorted-map :a 1 :b 2 :c 3))
; => clojure.lang.PersistentTreeMap

(class (hash-map :a 1 :b 2 :c 3))
; => clojure.lang.PersistentHashMap

您还需要注意不要无意中更改地图类型,例如:

(class (into {} (map #(vector (key %) (inc (val %))) (sorted-map :a 1))))
; => clojure.lang.PersistentArrayMap

最好不要依赖地图中条目的顺序,所以如果你能想到一种方法来实现你想要的东西而不依赖于地图中条目的顺序那么你应该强烈考虑它。

答案 1 :(得分:1)

地图无序,无法保证订单。因此,即使使用array-map,也不要编写依赖于它的代码。

地图的任何特定实例都保证以相同的顺序(通过seq,keys,vals等)返回条目,使得(键m)和(vals m)“匹配”。

如果您需要有序地图,请尝试https://github.com/amalloy/ordered