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

How to remove element from mutable vector?

提问人:blekione 提问时间:5/4/2016 最后编辑:blekione 更新时间:5/5/2016 访问量:213

问:

我知道如何创建可变向量:

(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"))

但这行不通。如何从可变向量中删除元素?

编辑: 集合实际上不一定是矢量的。我找到了集合的解决方案,但如果有人会建议矢量的解决方案,我会等待。

Vector Clojure 可变

评论


答:

2赞 leetwinski 5/4/2016 #1

你的错误是你把 arg 传递给函数,而它实际上接受一个谓词。在你的情况下,这个会起作用(虽然不正确,但制作一个列表而不是一个向量):"test"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. 你为什么要使用?你会在一些交易中使用它吗?如果没有,我建议你搬到一个(因为它也是线程安全的)refatom

    user> (def my-atom (atom []))
    #'user/my-atom
    
    user> (swap! my-atom conj "hello")
    ["hello"]
    
    user> (swap! my-atom #(remove #{"hello"} %))
    ()
    

评论

0赞 blekione 5/4/2016
你能证实我的理解吗?使用该构造,我们实际上不会修改集合,而是将引用更改为指向新创建的可变向量。我说得对吗?@my-vector
2赞 leetwinski 5/4/2016
事实上,没有可变向量,而是可变引用。你的向量始终保持不可变,而引用指向一个新构造的向量(clojure 的数据模型使它成为一个相当便宜的操作)
2赞 leetwinski 5/4/2016
嗯,实际上有可变的结构,例如瞬态,(clojure.org/reference/transients),但它是更高级的优化点,所以要谨慎对待
0赞 blekione 5/4/2016
所以我做对了。为了回答你的问题,为什么我使用这样的结构。好吧,这就是我可以在互联网上找到的。我是 Clojure 初学者,我试图创建“可变”集合,但没有实际研究如何去做。有问题的构造实际上是在 stackoverflow 上找到的:stackoverflow.com/a/5554870/5026241。原子是我接下来的书的下一章,但我需要在星期五:)完成我的任务。
1赞 leetwinski 5/5/2016
那么我可能会建议你花几个小时阅读一些适当的语言介绍,这会更有效率,然后阅读一些关于 SO ) braveclojure.com/clojure-for-the-brave-and-true 的随机帖子
0赞 blekione 5/4/2016 #2

正如我在编辑中指定的那样,集合不一定是真正的矢量。@leetwinski发布了如何为矢量执行此操作的答案,但是如果我决定使用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))
=>#{}

评论

1赞 leetwinski 5/4/2016
我想你在最后一行的意思。disj(dosync (alter my-set disj "test"))