2012-02-15 766 views
7

Estoy usando un vector de mapas que se define como referencia.clojure - eliminar un elemento de un vector de referencia

quiero eliminar un solo mapa del vector y sé que para eliminar un elemento de un vector debería usar subvec.

mi problema es que no pude encontrar una manera de implementar el subvec sobre un vector de referencia. intenté hacerlo usando: (dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))), de modo que el seq devuelto de la función vec estará ubicado en el índice 0 del vector, pero no funcionó.

¿Alguien tiene una idea de cómo implementar esto?

gracias

+0

Usar un vector para almacenar algo que querrás eliminar de forma aleatoria suele ser la opción incorrecta; no pueden hacerlo de manera eficiente y, como resultado, las características del idioma para hacer esto con ellos son incómodas. Considere el uso de una lista/seq en su lugar. – amalloy

Respuesta

5

commute (al igual que alter) necesita una función que se aplica al valor de la referencia.

Así que tendrá que algo como:

;; define your ref containing a vector 
(def v (ref [1 2 3 4 5 6 7])) 

;; define a function to delete from a vector at a specified position 
(defn delete-element [vc pos] 
    (vec (concat 
     (subvec vc 0 pos) 
     (subvec vc (inc pos))))) 

;; delete element at position 1 from the ref v 
;; note that communte passes the old value of the reference 
;; as the first parameter to delete-element 
(dosync 
    (commute v delete-element 1)) 

@v 
=> [1 3 4 5 6 7] 

Nota al que separar el código para eliminar un elemento del vector es un general buena idea por varias razones:

  • Esta función es potencialmente reutilizable en otro lugar
  • Hace que su código de transacción sea más corto y autodescriptivo
+0

'(conteo vc)' es redundante como el tercer argumento para '(subvec vc)' –

+0

buen lugar, actualizado y gracias! – mikera

+0

gracias por la respuesta y las sugerencias. –

Cuestiones relacionadas