如何从可变向量中删除元素?

时间:2016-05-04 15:30:11

标签: vector clojure mutable

我知道如何创建可变载体:

(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的解决方案,我会等待。

2 个答案:

答案 0 :(得分:2)

你的错误是你将"test" arg传递给remove函数,而它确实接受了一个谓词。在你的情况下,这一个工作(虽然不正确,制作一个列表而不是矢量):

(dosync (alter my-vector #(remove #{"test"} %)))

要保持它是一个向量,你必须这样做:

(dosync (alter my-vector #(vec (remove #{"test"} %))))

是什么让我对你的榜样感到好奇:

  1. 你为什么要使用这种奇怪的结构:

    (defn create-vector []
      (intern *ns* (symbol "my-vector" (ref []))))
    

    而非(def my-vector (ref []))

  2. 为什么要使用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))
=>#{}
相关问题