我知道如何创建可变载体:
(defn create-vector []
(intern *ns* (symbol "my-vector" (ref []))
=>my-namespace/my-vector
我知道如何向该向量添加元素:
(dosync (alter my-vector conj "test"))
=>["test"]
现在我的可变向量中有"test"
个字符串。但我怎么能删除它?我试图使用延迟序列函数remove
(dosync (alter my-vector remove "test"))
但它不起作用。如何从可变载体中删除元素?
编辑: 该集合实际上不一定是矢量。我找到了set的解决方案,但如果有人建议使用vector的解决方案,我会等待。
答案 0 :(得分:2)
你的错误是你将"test"
arg传递给remove
函数,而它确实接受了一个谓词。在你的情况下,这一个工作(虽然不正确,制作一个列表而不是矢量):
(dosync (alter my-vector #(remove #{"test"} %)))
要保持它是一个向量,你必须这样做:
(dosync (alter my-vector #(vec (remove #{"test"} %))))
是什么让我对你的榜样感到好奇:
你为什么要使用这种奇怪的结构:
(defn create-vector []
(intern *ns* (symbol "my-vector" (ref []))))
而非(def my-vector (ref []))
为什么要使用ref
?你会在一些交易中使用它吗?如果没有,我建议你转移到atom
(因为它也是线程安全的)
user> (def my-atom (atom []))
#'user/my-atom
user> (swap! my-atom conj "hello")
["hello"]
user> (swap! my-atom #(remove #{"hello"} %))
()
答案 1 :(得分:0)
正如我的编辑中所指出的,集合并不一定是真正的矢量。 @leetwinski发布了答案如何为vector做到这一点,但如果我决定使用set我找到了其他解决方案。因此,如果我们创建的设置方式与将[]
替换为#{}
的问题相同:
(defn create-vector []
(intern *ns* (symbol "my-set" (ref #{}))
=>my-namespace/my-vector
并添加元素:
(dosync (alter my-set conj "test"))
=>#{"test"}
,我们可以将其删除
(dosync (alter my-set disj item))
=>#{}