2012-02-15 17 views
7

Sto utilizzando un vettore di mappe definito come riferimento.clojure: cancella un elemento da un vettore ref

Voglio eliminare una singola mappa dal vettore e so che per eliminare un elemento da un vettore dovrei usare subvec.

il mio problema è che non sono riuscito a trovare un modo per implementare il subvec su un vettore di riferimento. ho provato a farlo utilizzando: (dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))), in modo che il seq restituito dalla funzione vec si trova sull'indice 0 del vettore ma non ha funzionato.

qualcuno ha un'idea di come implementarlo?

grazie

+0

L'utilizzo di un vettore per archiviare qualcosa che si desidera eliminare in un modo ad accesso casuale è di solito la scelta sbagliata - non possono farlo in modo efficiente e, di conseguenza, le funzionalità del linguaggio per fare ciò con loro sono scomode. Considera solo l'uso di una lista/seq, invece. – amalloy

risposta

5

commute (come alter) necessita di una funzione che verrà applicato al valore del riferimento.

Così si vuole qualcosa di simile:

;; 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 il che separare il codice per eliminare un elemento dal vettore è un generalmente buona idea per diversi motivi:

  • Questa funzione è altrove potenzialmente riutilizzabile
  • Rende il codice della transazione più breve e più auto-descrittivo
+0

'(count vc)' è ridondante come il terzo argomento di '(subvec vc)' –

+0

ottimo spot, aggiornato e grazie! – mikera

+0

grazie per la risposta e i suggerimenti. –

Problemi correlati