2016-06-29 10 views

Antwort

7

select-keys gibt eine Karte zurück, die nicht geordnet ist, so dass Sie sich nicht darauf verlassen können. Kleine Karten werden als Arrays dargestellt, die die Reihenfolge beibehalten, aber dies wird unterbrochen, wenn die Größe zunimmt, z.

(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]] 
0

Es ist keine zuverlässige Funktion Aufträge zu erhalten, sowie keys und vals die die Reihenfolge der nicht erhalten, wie Sie die Karte definiert. Der zuverlässigste Weg ist die Verwendung eines loop/recur, wenn Sie einen geordneten Vektor von kv (oder auch reduce) ausgeben möchten. Wenn Sie nur geordnete Werte wünschen, können Sie juxt verwenden.

Ich würde hinzufügen, dass pragmatisch hashmaps nicht zur Darstellung geordneter Daten gedacht sind.

+0

Yup, eine assoziative ungeordnete Datenstruktur zielt nicht darauf ab, geordnete Daten zu sammeln, aber Clojure hat immer noch 'sorted-map' und' sorted-map-by' und das hat mich zu diesem Thema provoziert. – foki

1

Wenn die Bestellung ein ziemlich einfacher ist, können Sie einfach die Karte sortieren, indem sorted-map-by mit:

(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]] 

Auch wenn die Bestellung nicht einfach ist, können Sie einen benutzerdefinierten Komparator schreiben. Dies ist voller Fallstricke, aber es gibt a guide das ist sehr gut. Es ist nicht, was Sie ursprünglich waren, aber es ist relevant.

+1

Beachten Sie, dass '(sorted-map-by compare)' äquivalent zu '(sorted-map)' ist. –