2016-05-04 8 views
1

Ich weiß, wie wandelbar Vektor zu erstellen:Wie kann man Elemente aus einem veränderbaren Vektor entfernen?

(defn create-vector [] 
    (intern *ns* (symbol "my-vector" (ref [])) 
=>my-namespace/my-vector 

Ich weiß, wie zu diesem Vektor hinzufügen Element:

(dosync (alter my-vector conj "test")) 
=>["test"] 

Jetzt habe ich "test" Zeichenfolge in meinem wandelbar Vektor. Aber wie kann ich es entfernen? Ich habe versucht, faul-Sequenz Funktion remove

(dosync (alter my-vector remove "test")) 

zu verwenden, aber es funktioniert nicht. Wie kann ich Elemente aus einem veränderbaren Vektor entfernen?

EDIT: Die Sammlung muss nicht wirklich Vektor sein. Ich habe eine Lösung für die Menge gefunden, werde aber warten, wenn jemand eine Lösung für den Vektor vorschlagen wird.

Antwort

2

Ihr Fehler ist, dass Sie die "test" arg zu remove Funktion übergeben, während es wirklich ein Prädikat akzeptiert. In Ihrem Fall dieses Wold Arbeit (unproperly aber eine Liste anstelle eines Vektors zu machen):

(dosync (alter my-vector #(remove #{"test"} %))) 

zu halten, einen Vektor Sie würden es zu tun haben:

(dosync (alter my-vector #(vec (remove #{"test"} %)))) 

was macht mich neugierig über Ihr Beispiel:

  1. , warum Sie diese seltsame Konstruktion verwenden würde:

    (defn create-vector [] 
        (intern *ns* (symbol "my-vector" (ref [])))) 
    

    statt nur (def my-vector (ref []))

  2. warum verwenden Sie ref alle an? würden Sie es in einer Transaktion verwenden? wenn nicht, würde ich vorschlagen, Sie auf ein atom zu bewegen

    user> (def my-atom (atom [])) 
    #'user/my-atom 
    
    user> (swap! my-atom conj "hello") 
    ["hello"] 
    
    user> (swap! my-atom #(remove #{"hello"} %)) 
    () 
    
+0

Können Sie sich meine bestätigen Verstehen? Mit diesem Konstrukt ändern wir eigentlich nicht die Sammlung, sondern ändern stattdessen den Verweis @ my-vector auf den neu erstellten veränderbaren Vektor. Habe ich recht? –

+2

tatsächlich gibt es keine veränderbaren Vektoren, aber veränderbare * Referenzen *. Ihre Vektoren bleiben immer unveränderlich, während Referenzpunkte auf eine neu konstruierte (das Datenmodell von clojure macht es zu einer ziemlich billigen Operation) – leetwinski

+2

Nun, tatsächlich gibt es veränderbare Strukturen, Transienten zum Beispiel, (http: // clojure.org/reference/transients), aber es ist eher fortgeschrittener Optimierungspunkt, also nähern Sie sich mit Vorsicht – leetwinski

0

angegeben (da es auch sicher ist Thread) Wie in meinem bearbeiten, muss Sammlung nicht wirklich Vektor sein. @leetwinski hat eine Antwort geschrieben, wie man es für Vektor macht, aber wenn ich mich entscheiden würde, Set zu verwenden, fand ich andere Lösung. Also, wenn wir die gleiche Art und Weise wie in Frage zu ersetzen []-#{} Set erstellen:

(defn create-vector [] 
    (intern *ns* (symbol "my-set" (ref #{})) 
=>my-namespace/my-vector 

und fügen Element:

(dosync (alter my-set conj "test")) 
=>#{"test"} 

, können wir entfernen es

(dosync (alter my-set disj item)) 
=>#{} 
+1

Ich denke du hast 'disj' in der letzten Zeile gemeint. '(dosync (alter my-set disj" test "))' – leetwinski

+0

Ja. Ich korrigiere es schon. Vielen Dank. –