2009-06-02 20 views
32

En primer lugar, asumir cada uno secuencias específicas de estructura tendrían diferentes formas de eliminar un elemento: vectores podría ser mediante un índice, Lista podría ser eliminar primero o el último, Establecer debe pasar del artículo real para eliminar , etc.¿Cómo puedo eliminar un elemento de una secuencia en Clojure?

En segundo lugar, supongo que hay algunos métodos de eliminación que son independientes de la estructura; funcionan en seq interfaz.

Dado que las secuencias son inmutables en Clojure, sospecho que lo que realmente está haciendo es hacer una copia barata del original, solo que sin el artículo original. Esto significa que la comprensión de la lista podría utilizarse para la eliminación, pero sospecho que sería innecesariamente detallado.

Por favor, da algunos ejemplos idiomáticos de las diferentes formas de eliminar elementos de las secuencias de Clojure.

Respuesta

41

No hay una interfaz única para eliminar elementos de todos los tipos de estructura de datos de Clojure, posiblemente debido a las diferentes características de rendimiento.

(disj #{:foo :bar} :foo)  ; => #{:bar} 
(dissoc {:foo 1 :bar 2} :foo) ; => {:bar 2} 
(pop [:bar :foo])    ; => [:bar] 
(pop (list :foo :bar))   ; => (:bar) 

Estos también funcionan (volviendo un seq):

(remove #{:foo} #{:foo :bar})  ; => (:bar) 
(remove #{:foo} [:foo :bar])  ; => (:bar) 
(remove #{:foo} (list :foo :bar)) ; => (:bar) 

Esto no funciona para hash mapas porque cuando iterar sobre un mapa, se obtiene pares clave/valor. Pero esto funciona:

(remove (fn [[k v]] (#{:foo} k)) {:foo 1 :bar 2}) ; => ([:bar 2]) 
+0

Gracias Brian, esto es lo que estaba buscando. Su mención de subvec no parece coincidir con la documentación: "Devuelve un vector persistente de los elementos en vector desde el inicio (inclusive) hasta el final (exclusivo). Si no se proporciona el extremo, el valor predeterminado es (vector de conteo)". ¿Quiso decir que podría hacer dos llamadas subvec para omitir el elemento "eliminado"? – rcampbell

+0

Sí, eso es lo que quise decir. En retrospectiva, puede ser demasiado torpe incluso para considerar. Lo eliminaré de la publicación. –

+0

['subvec'] (http://clojuredocs.org/clojure_core/clojure.core/subvec) vale la pena mencionar (para vectores), porque opera en O (1) tiempo. –

2

Como una extensión de la respuesta de Brian Carper. Depende de lo que harás con el resultado. Si está pasando el resultado a algo que quiere trabajar en todo el conjunto de datos (es decir, imprimirlo) es idiomático hacer un seq y usar el filtro o eliminar para resolver el problema perezosamente. Si, por otro lado, está modificando la estructura de datos para ahorrar para varios usos posteriores, la creación de un seq perderá sus características de actualización favorables, por lo que en este caso es mejor utilizar la función de actualización específica de esa estructura de datos.

Cuestiones relacionadas