Как я могу сортировать набор карт clojure? - PullRequest
17 голосов
/ 22 марта 2011

У меня есть набор карт что-то вроде этого:

#{
  {:name "a" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
  {:name "c" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
}

: и я хочу попасть в упорядоченный список, очень похожий на sql order-by name:

[
  {:name "a" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "c" :value "b" ... more stuff here}
]

: как я могу это сделать?

Ответы [ 5 ]

31 голосов
/ 22 марта 2011

Функция Сортировка по - это то, что вы ищете:

(def s
  #{
    {:name "d" :value "b" }
    {:name "b" :value "b" }
    {:name "c" :value "b" }
    })
(sort-by :name s)
7 голосов
/ 22 марта 2011

sort-by - отличный ответ, который делает код намного лучше в простых случаях, когда он работает.Кроме того, функция сортировки может взять функцию для извлечения ключа сравнения из каждой карты, если вам нужно выполнить некоторую обработку каждого элемента.В этом примере я использую функцию сортировки, которая извлекает каждое имя и затем сравнивает их по строкам.

(sort #(compare (:name %1) (:name %2)) data)
=>  ({:name "a", :value "b"} {:name "b", :value "b"} {:name "c", :value "b"})

это полезно, если в ваших коллекциях сравниваются разные имена:

(sort #(compare (:value %1) (:name %2)) data)
=> ({:name "a", :value "b"} {:name "c", :value "b"} {:name "b", :value "b"})

функция compare является лучшей версией java .compareto (), потому что она правильно обрабатывает nil и правильно сравнивает коллекции clojure.это в основном короткий путь для использования.Оператор в большинстве случаев

(sort #(. (:name %1) (compareTo (:name %2))) data)
=> ({:name "a", :value "b"} {:name "b", :value "b"} {:name "c", :value "b"})
5 голосов
/ 22 марта 2011

(def set-of-maps #{{:name "d"}, {:name "b"}, {:name "a"}})

-> clojure.core / sort-by

(sort-by :name set-of-maps)

; => ({:name "a", :value "b"} {:name "c", :value "b"} {:name "d", :value "b"})

4 голосов
/ 22 марта 2011

sort-by - это то, что вы хотите, но, пожалуйста, опубликуйте фрагменты, которые на самом деле являются действительным кодом; Я потратил немало времени, пытаясь выяснить проблему, которая возникла из-за того, что #{{:name "a" :value "b"} {:name "a" :value "b"}} делает читателя недовольным.

2 голосов
/ 24 февраля 2013

Я полагаю, что фрагмент от радости clojure - самый лучший.

(def plays [{:band "Burial",     :plays 979,  :loved 9}
           {:band "Eno",        :plays 2333, :loved 15}
           {:band "Bill Evans", :plays 979,  :loved 9}
           {:band "Magma",      :plays 2665, :loved 31}])

(def sort-by-loved-ratio (partial sort-by #(/ (:plays %) (:loved %))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...