2015-12-21 65 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來代替 - 它提供持久有序集合和地圖,內置數據結構(一組或地圖+一個矢量來跟蹤插入順序)。