ejemplos - En Clojure, ¿cuándo debería usar un vector sobre una lista, y viceversa?
clojure ejemplos (5)
Cuándo usar un vector:
- Rendimiento de acceso indexado: obtiene ~ O (1) costo para el acceso indexado frente a O (n) para las listas
- Anexar - con conj es ~ O (1)
- Notación conveniente: me resulta más fácil escribir y leer [1 2 3] que ''(1 2 3) para una lista literal en circunstancias en las que cualquiera funcionaría.
Cuándo usar una lista:
- Cuando desee acceder a él como una secuencia (ya que las listas admiten directamente seq sin tener que asignar nuevos objetos)
- Anteponer - agregar al inicio de una lista con contras o preferiblemente conj es O (1)
Leí que los vectores no son seqs, sino que las listas son. No estoy seguro de cuál es la razón para usar uno sobre el otro. Parece que los vectores son los que más se usan, pero ¿hay alguna razón para eso?
Los vectores tienen O (1) tiempos de acceso aleatorio, pero deben ser preasignados. Las listas se pueden extender dinámicamente, pero el acceso a un elemento aleatorio es O (n).
Si ha realizado mucho la programación de Java y está familiarizado con el marco de recopilación de Java, piense en listas como LinkedList
y vectores como ArrayList
. Entonces puede elegir recipientes de la misma manera.
Para mayor aclaración: si tiene la intención de agregar elementos individualmente al frente o al final de la secuencia, una lista vinculada es mucho mejor que un vector, ya que no es necesario mezclar los elementos cada vez. Sin embargo, si desea obtener elementos específicos (no cerca del frente o la parte posterior de la lista) con frecuencia (es decir, acceso aleatorio), querrá usar vectores.
Por cierto, los vectores pueden convertirse fácilmente en seqs.
user=> (def v (vector 1 2 3))
#''user/v
user=> v
[1 2 3]
user=> (seq v)
(1 2 3)
user=> (rseq v)
(3 2 1)
Una vez más, parece que he respondido mi propia pregunta poniéndome impaciente y preguntándola en #clojure en Freenode. Lo bueno es que se alientan sus propias preguntas en .com: D
Tuve una discusión rápida con Rich Hickey, y aquí está lo esencial.
[12:21] <Raynes> Vectors aren''t seqs, right?
[12:21] <rhickey> Raynes: no, but they are sequential
[12:21] <rhickey> ,(sequential? [1 2 3])
[12:21] <clojurebot> true
[12:22] <Raynes> When would you want to use a list over a vector?
[12:22] <rhickey> when generating code, when generating back-to-front
[12:23] <rhickey> not too often in Clojure
solo una nota rápida:
"I read that Vectors are not seqs, but Lists are."
las secuencias son más genéricas que las listas o vectores (o mapas o conjuntos).
Es lamentable que REPL imprima listas y secuencias de la misma manera porque realmente hace que parezca que las listas son secuencias aunque sean diferentes. la función (seq) hará una secuencia a partir de una gran cantidad de cosas diferentes, incluidas las listas, y luego puede alimentar ese seq a cualquiera de la plétora de funciones que hacen cosas ingeniosas con seqs.
user> (class (list 1 2 3))
clojure.lang.PersistentList
user> (class (seq (list 1 2 3)))
clojure.lang.PersistentList
user> (class (seq [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq
Sec tiene un atajo que devuelve su argumento si ya es un seq:
user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
true
user> (identical? (list 1 2 3) (seq (list 1 2 3)))
false
static public ISeq seq(Object coll){
if(coll instanceof ASeq)
return (ASeq) coll;
else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
else
return seqFrom(coll);
}
las listas son secuencias, aunque otras cosas también lo son, y no todas las secuencias son listas.