Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure - delete an element from a ref vector

I'm using a vector of maps which defined as a referece.

i want to delete a single map from the vector and i know that in order to delete an element from a vector i should use subvec.

my problem is that i couldn't find a way to implement the subvec over a reference vector. i tried to do it using: (dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))), so that the seq returned from the vec function will be located on index 0 of the vector but it didn't work.

does anyone have an idea how to implement this?

thanks

like image 561
I.N. Avatar asked Feb 15 '12 12:02

I.N.


1 Answers

commute (just like alter) needs a function that will be applied to the value of the reference.

So you will want something like:

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

Note the that separating out the code to delete an element from the vector is a generally good idea for several reasons:

  • This function is potentially re-usable elsewhere
  • It makes your transaction code shorter and more self-desciptive
like image 175
mikera Avatar answered Sep 29 '22 18:09

mikera