clojure - удалить элемент из вектора ref - PullRequest
7 голосов
/ 15 февраля 2012

Я использую вектор карт, который определен как ссылка.

Я хочу удалить одну карту из вектора, и я знаю, что для удаления элемента из вектора я должен использовать subvec.

моя проблема в том, что я не мог найти способ реализации subvec над опорным вектором. я пытался сделать это с помощью: (dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))), так что возвращаемый из функции vec seq будет расположен в индексе 0 вектора, но он не работал.

У кого-нибудь есть идеи, как это реализовать?

спасибо

1 Ответ

5 голосов
/ 15 февраля 2012

commute (так же, как alter ) требуется функция, которая будет применена к значению ссылки.

Так что вам понадобится что-то вроде:

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

Обратите внимание, что разделение кода для удаления элемента из вектора обычно является хорошей идеей по нескольким причинам:

  • Эта функция потенциально может использоваться повторно в других местах
  • Это делает ваш код транзакции короче и более информативным
...