Clojure - 从ref向量中删除元素

7
我正在使用一个由引用定义的地图向量。
我想从向量中删除单个映射,我知道要从向量中删除元素,应该使用subvec
我的问题是我找不到一种在引用向量上实现subvec的方法。 我尝试使用:(dosync (commute v assoc 0 (vec (concat (subvec @v 0 1) (subvec @v 2 5))))),这样从vec函数返回的序列将位于向量的索引0,但它没有起作用。
有谁有想法如何实现这个吗?
谢谢

使用向量来以随机访问方式存储需要删除的内容通常是错误的选择 - 它们不能有效地完成此操作,因此使用它们进行此操作的语言特性很笨拙。考虑只使用列表/序列即可。 - amalloy
1个回答

5

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]

注意,将从向量中删除元素的代码分离出来通常是一个很好的想法,原因如下:

  • 这个函数有潜在的可重用性
  • 它使您的事务代码更短,更易于理解自我描述

作为 (subvec vc) 的第三个参数,(count vc) 是多余的。 - Rafał Dowgird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接