2009-10-06 18 views

Odpowiedz

4

Posortowaną mapę używasz, określając porównanie, a następnie pary klucz-wartość. Komparator jest funkcją, która pobiera dwa klucze i zwraca wartość -1, 0 lub 1 w zależności od tego, czy pierwszy klucz jest mniejszy, równy lub większy niż drugi klucz.

Przykład:

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} 

Ponieważ funkcja comparisson zajmuje tylko klucze jako argumenty, nie można wykorzystać do sortowania według wartości.

Nie ma sposobu na posortowaną mapę, na której mapa jest posortowana według wartości. Gdyby tak było, nie byłoby możliwe znalezienie wpisu za pomocą klucza, ponieważ nie można było użyć zamówienia w celu ustalenia, gdzie znajduje się wpis (ponieważ zamówienie nie zależy od klucza).

+1

Na stronie doc myślę można przeczytać coś przeciwnego czyli „Jeśli chcesz, aby posortować mapę zgodnie z wartościami, ...” http://clojuredocs.org/clojure_core/clojure.core/sorted -map-by – tangrammer

16

Innym sposobem jest porównanie wartości z oryginalnej mapy w funkcji porównywania.

(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

Pamiętaj, że w twoim rozwiązaniu jest błąd, sprawdź to: (def my-map {: chad 3: bob 5: alice 3: sammy 4}) Twoim rozwiązaniem: alice 3 będzie odcięte od wynikowej mapy. –

+0

@AlfredoDiNapoli Zauważyłem ten sam problem. Udało mi się to naprawić, używając <= zamiast porównania w anonimowej funkcji. – Rafael

+0

Czyż @Rafael nie jest pomysłem użycia '<=' zamiast 'compare' wiążącego mój kod do implementacji' sorted-map-by'? Clojure Docs odnosi się do tego przypadku "sorted-map-by" i proponuje takie rozwiązanie: '(do (posortowane-map-by (fn [key1 key2] (porównaj [(key1 my-map2) key1] [ (key2 my-map2) key2]))) my-map2) 'zamiast tego – mjaskowski

Powiązane problemy