我来自Python,默认情况下不会对地图(即dicts)进行排序.开始学习Clojure,我遇到了这个:
(def point {:x 5 :y 7}) => #'user/point point => {:x 5, :y 7} (let [{:keys [x y]} point] (println "x:" x "y:" y)) x: 5 y: 7
在我看来,为了使这种解构工作,人们将不得不依赖于所订购的地图(当然,还记得订单).真的吗?
Clojure有三种内置的地图类型:数组映射,哈希映射和有序映射.
其中,哈希映射和有序映射是无序的,但实际上是有序数组映射:这在clojure.org官方文档的数据结构部分中有解释.
然而,重要的是要注意,阵列映射主要用于性能原因 - 小地图文字(≤8个条目)被编译为数组映射而不是散列映射,并且assoc
新的键到数组映射将返回哈希映射,如果它导致它超过大小阈值.可以通过显式调用来构造更大的数组映射clojure.core/array-map
,但是数组映射操作是O(n),因此在存在太多条目时变得相当慢,因此这不是通用有序映射数据结构.
如果你需要一个能够提供良好性能而不管大小的有序地图,你应该使用Alan Malloy的/ Flatland的命令 - 它提供了由内置数据结构支持的持久有序集和映射(一组或一个映射+一个向量)跟踪插入顺序).
Clojure地图不是有序的,尽管有一个这样的东西sorted-map
.您正在获得一致的订单,因为您使用密钥来访问值.看看更改密钥名称时会发生什么......
user=> point {:a 5, :b 7} user=> (let [{:keys [x y]} point] #_=> (println "x:" x "y:" y)) x: nil y: nil nil user=> (let [{:keys [a b]} point] #_=> (println "a:" a "b:" b)) a: 5 b: 7
我有一个类似的问题,其答案与您的问题相关.