2009-10-06 6 views

Antwort

4

Sie verwenden sorted-map-by, indem Sie einen Vergleich angeben, gefolgt von den Schlüssel-Wert-Paaren. Der Komparator ist eine Funktion, die zwei Tasten nimmt und -1, 0 oder 1 zurückgibt, abhängig davon, ob der erste Schlüssel kleiner, gleich oder größer als der zweite Schlüssel ist.

Beispiel:

user=> (sorted-map-by (fn [k1 k2] (compare (mod k1 10) (mod k2 10))) 10 1 23 4 2 5) 
{10 1, 2 5, 23 4} 

Da die comparisson Funktion nur Tasten als Argumente übernimmt, können Sie das nicht verwenden, indem Sie die Werte zu sortieren.

Es gibt keine Möglichkeit, eine sortierte Karte zu haben, in der die Karte nach den Werten sortiert ist. Wenn dies der Fall wäre, wäre es nicht möglich, einen Eintrag nach Schlüssel zu finden, da Sie den Auftrag nicht verwenden können, um festzustellen, wo sich der Eintrag befindet (da der Auftrag nicht vom Schlüssel abhängt).

+1

In doc Seite glaube ich Ihnen das Gegenteil lesen bedeutet „Wenn Sie die Karte sortieren nach den Werten wünschen, ...“ http://clojuredocs.org/clojure_core/clojure.core/sorted -map-by – tangrammer

16

Eine andere Möglichkeit besteht darin, die Werte der Originalkarte innerhalb der Vergleichsfunktion zu vergleichen.

(def my-map {:chad 3 :bob 5 :sammy 4}) 

;; sort by keys ascending 
(into (sorted-map) my-map) 
=> {:bob 5, :chad 3, :sammy 4} 

;; sort by values ascending 
(into (sorted-map-by (fn [key1 key2] (compare (key1 my-map) (key2 my-map)))) my-map) 
=> {:chad 3, :sammy 4, :bob 5} 

;; sort by values descending 
(into (sorted-map-by (fn [key1 key2] (compare (key2 my-map) (key1 my-map)))) my-map) 
=> {:bob 5, :sammy 4, :chad 3} 
+2

Vorsicht, es gibt einen Fehler in Ihrer Lösung, überprüfen Sie dies: (def my-map {: tschad 3: bob 5: alice 3: sammy 4}) Mit Ihrer Lösung wird: alice 3 sein abgeschnitten von der resultierenden Karte. –

+0

@AlfredoDiNapoli Ich bemerkte das gleiche Problem. Ich konnte es beheben, indem ich <= anstelle von Vergleichen in der anonymen Funktion verwendete. – Rafael

+0

Ist nicht @Rafael Idee der Verwendung von '<=' anstelle von 'compare' meinen Code an die Implementierung von' sorted-map-by' zu binden? Clojure Docs bezieht sich auf den Anwendungsfall 'sorted-map-by' und schlägt eine solche Lösung vor: ' (in (sorted-map-by) (fn [key1 key2] (vergleiche [key1 my-map2) key1] [ (key2 my-map2) key2]))) stattdessen my-map2) – mjaskowski