2015-12-21 62 views
2

我来自Python,默认情况下地图(即字典)没有排序。开始学习Clojure的,我碰到这个传来: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 

在我看来,对于这个解构的工作一个人必须要依靠在地图上被排序(当然,记住顺序)。真的吗?

回答

6

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 

我有一个similar question有一个公认的答案,是有关你的问题。

+0

哦!谢谢,我没有意识到实际的键被用作参数。这让我感觉更好。大声笑 –

5

Clojure有三种内置地图类型:数组地图,散列地图和排序地图。

其中,哈希映射和有序映射是无序的,但数组映射实际上是有序的:这在the data structures section的官方文档clojure.org中有解释。

然而,重要的是要注意,数组映射主要用于性能方面的原因 - 小地图文字(≤8条目)被编译为数组映射而不是散列映射,并将新的键映射到数组映射上如果它导致它超过大小阈值,则返回一个哈希映射。可以通过明确地调用clojure.core/array-map来构造更大的数组映射,但是数组映射操作是O(n),因此在出现太多条目时变得相当慢,所以这不是通用的有序映射数据结构。

如果您需要能够提供良好性能(无论大小如何)的有序地图,则应该使用Alan Malloy的/ Flatland的ordered来代替 - 它提供持久有序集合和地图,内置数据结构(一组或地图+一个矢量来跟踪插入顺序)。