2011-03-22 10 views
17

que tienen un conjunto de mapas o menos así:¿Cómo puedo ordenar un conjunto de mapas clojure?

#{ 
    {: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} 
} 

: y yo quiero llegar a una lista ordenada, muy parecido a SQL orden por su nombre:

[ 
    {: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} 
] 

: ¿cómo puedo hacer ¿esta?

Respuesta

31

Función sort-by es lo que está buscando:

(def s 
    #{ 
    {:name "d" :value "b" } 
    {:name "b" :value "b" } 
    {:name "c" :value "b" } 
    }) 
(sort-by :name s) 
+0

Simple, preciso, conciso. Funcionó como un encanto @Leonel – William

7

ordenar por es una gran respuesta, y hace que el código sea mucho mejor en los casos simples en los que funciona. Además, la función de ordenación puede tomar una función para extraer la clave comparason de cada mapa en caso de que necesite realizar algún procesamiento en cada elemento. En este ejemplo, utilizo una función de clasificación que extrae cada nombre y luego hace una comparación de cadenas en ellos.

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

Esto es útil si sus colecciones tenían diferentes nombres para ser comparado:

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

la función compare es una mejor versión de .compareto de Java() porque maneja adecuadamente nula y compara colecciones clojure adecuadamente . es básicamente un atajo para usar el. opperator en la mayoría de los casos

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

No entiendo, ¿podría explicarme un poco más por favor cómo funcionaría esto? – Zubair

5

(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

sort-by es lo que quiere, pero por favor publique fragmentos que en realidad son códigos válidos; Perdí un poco de tiempo tratando de descubrir un problema que terminó siendo porque #{{:name "a" :value "b"} {:name "a" :value "b"}} hace que el lector pierda el conocimiento.

+0

"más cosas aquí" habría evitado el error duplicado de la clave. –

2

Creo que el fragmento de la alegría de clojure es el más adecuado.

(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 %)))) 
Cuestiones relacionadas