2012-02-15 9 views
7

Używam wektora map, które zdefiniowano jako referecję.clojure - usunięcie elementu z wektora odniesienia

Chcę usunąć pojedynczą mapę z wektora i wiem, że w celu usunięcia elementu z wektora należy użyć subvec.

Mój problem polega na tym, że nie mogłem znaleźć sposobu na wdrożenie subvec w stosunku do wektora odniesienia. Próbowałem zrobić to, używając: (dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))), tak aby seq zwrócony z funkcji vec będzie zlokalizowany na indeksie 0 wektora, ale nie zadziałał.

Czy ktoś ma pomysł, jak to wdrożyć?

dzięki

+0

Używanie wektora do przechowywania czegoś, co chcesz usunąć w trybie dostępu losowego, jest zwykle złym wyborem - nie mogą tego zrobić wydajnie, a zatem funkcje językowe do robienia tego z nimi są niezręczne. Zastanów się, używając zamiast tego listy/seq. – amalloy

Odpowiedz

5

commute (podobnie jak alter) potrzebuje funkcję, która zostanie zastosowana do wartości odniesienia.

więc będziemy chcieli coś takiego:

;; 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] 

Zanotować że oddzielenie kodu, aby usunąć element z wektora jest generalnie dobry pomysł z kilku powodów:

  • Funkcja ta jest potencjalnie do ponownego użycia w innym miejscu
  • Dzięki temu kod transakcji jest krótszy i bardziej samodyscyplinarny.
+0

'(count vc)' jest nadmiarowy jako trzeci argument dla '(subvec vc)' –

+0

dobre miejsce, zaktualizowane i dzięki! – mikera

+0

dzięki za odpowiedź i wskazówki. –

Powiązane problemy