2011-02-23 13 views

Respuesta

119

No forjemos et that trusty old into le permite tomar cualquier cosa seq capaz (list, vector, map, set, sorted-map) y un contenedor vacío que desee llenar, y lo pone into.

(into [] '(1 2 3 4)) ==> [1 2 3 4]   "have a lazy list and want a vector" 
(into #{} [1 2 3 4]) ==> #{1 2 3 4}  "have a vector and want a set" 
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2} "have a set of vectors want a map" 
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps" 

into es una envoltura alrededor de conj, que es la abstracción de base para la inserción de nuevas entradas adecuadamente en una colección basada en el tipo de la colección. El principio que hace que esto fluya tan bien es que Clojure está construido sobre abstracciones compostables, en este caso into en la parte superior de conj en la parte superior de la colección y seq.

Los ejemplos anteriores seguirían siendo componer bien si el receptor estaba siendo aprobada en en tiempo de ejecución: debido a que las abstracciones subyacentes (seq y conj) se implementan para todas las colecciones (y muchas de las colecciones de Java también), por lo que las abstracciones más altas no necesita preocuparse por muchos casos de esquina especiales relacionados con los datos.

+3

+1 para en ... vale la pena señalar que también funciona con contenedores originales no vacíos también (es decir, cuando desea agregar a una colección) – mikera

+8

También vale la pena señalar que porque 'into' utiliza' conj', doing ' (en '() some-seq) 'producirá una lista que es el * reverse * de some-seq, porque' conj' se refiere a las listas. – Chuck

+0

Vale la pena señalar que 'en 'utiliza transitorios (para la mayoría de los tipos de seq) para obtener mejores características de rendimiento que la mayoría de los otros medios de conversión. –

30

vec, set y generalmente into son sus amigos para "convertir" fácilmente a otro tipo de colección.

¿Cómo desea transformar un vector de mapas en un mapa de mapas? Necesita una clave, ¿puede proporcionar el uso con la entrada de muestra/salida esperada?

+0

perdón, quise decir un conjunto de mapas ... He modificado la pregunta ahora – Zubair

17

Para los vectores no es la función

user=> (vec '(1 2 3)) 
[1 2 3] 

vec Para secuencias perezosos existe la función

user=> (lazy-seq [1 2 3]) 
(1 2 3) 

lazy-seq Para convertir en conjuntos, existe la función set

user=> (set [{:a :b, :c :d} {:a :b} {:a :b}]) 
#{{:a :b} {:a :b, :c :d}} 
+4

Cuando tienes algo que no es perezoso, llamar 'lazy-seq' en lugar de' seq' solo agrega una indirecta inútil. Si realmente quieres devolver algo que no sea nada, incluso antes de que exista colectividad vacía, hay 'secuencia '. 'lazy-seq' es algo así como una construcción de bajo nivel. – cgrand

8

Para convertir un vector a una lista también se puede utilizar for, así:

=> (for [i [1 2 3 4]] i) 
(1 2 3 4) 

Cuando no se desea manipular los datos, sólo tiene que utilizar seq en el vector:

=> (seq [1 2 3]) 
(1 2 3) 
5

No es necesario convertir un vector en una lista. Clojure tratará un vector como trataría una lista, como una secuencia, cuando se requiera una secuencia.Por ejemplo,

user=> (cons 0 [1 2 3]) 
(0 1 2 3) 

Si tiene que asegurarse de que el vector está siendo tratado como una secuencia, envolverlo en seq:

user=> (conj [1 2 3] 0) ; treated as a vector 
[1 2 3 0] 

user=> (conj (seq [1 2 3]) 0) ; treated as a sequence 
(0 1 2 3) 

Si usted tiene un vector de mapas, y quieres un conjunto de mapas, no importa que el vector tenga mapas. Usted acaba de convertir el vector a un conjunto como de costumbre:

user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}]) 
#{{:a 1, :b 2} {"four" 4, "three" 3}} 
11

Una de las respuestas más para la conversión de una lista a un mapa (en aras de la exhaustividad) - a partir here:

(apply hash-map '(1 2 3 4)) 
;=>{1 2, 3 4} 
Cuestiones relacionadas