2012-02-15 39 views
7

Tôi đang sử dụng một vectơ bản đồ được định nghĩa là một tham chiếu.clojure - xóa một phần tử khỏi một vector ref

tôi muốn xóa một bản đồ khỏi vectơ và tôi biết rằng để xóa phần tử khỏi vectơ, tôi nên sử dụng subvec.

vấn đề của tôi là tôi không thể tìm cách triển khai subvec trên một vectơ tham chiếu. tôi đã cố gắng thực hiện việc đó bằng cách sử dụng: (dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))), sao cho seq trả về từ hàm vec sẽ nằm trên chỉ mục 0 của vectơ nhưng nó không hoạt động.

có ai có ý tưởng cách triển khai tính năng này không?

nhờ

+0

Sử dụng một vector để lưu trữ thứ bạn muốn xóa theo kiểu truy cập ngẫu nhiên thường là lựa chọn sai - chúng không thể làm điều đó một cách hiệu quả và kết quả là các tính năng ngôn ngữ để làm việc này với chúng thật khó xử. Hãy xem xét chỉ sử dụng một danh sách/seq thay thế. – amalloy

Trả lời

5

commute (giống như alter) cần một chức năng sẽ được áp dụng với giá trị của các tài liệu tham khảo.

Vì vậy, bạn sẽ muốn một cái gì đó như:

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

Lưu ý rằng tách ra mã để xóa một phần tử từ vector là một ý tưởng chung là tốt vì nhiều lý do:

  • Chức năng này khả năng có thể sử dụng lại ở nơi khác
  • Nó làm cho mã giao dịch của bạn ngắn hơn và tự mô tả hơn
+0

'(count vc)' là dự phòng làm đối số thứ ba cho '(subvec vc)' –

+0

vị trí tốt, được cập nhật và cảm ơn! – mikera

+0

cảm ơn câu trả lời và lời khuyên. –

Các vấn đề liên quan