提问人:blekione 提问时间:5/4/2016 最后编辑:blekione 更新时间:5/5/2016 访问量:213
如何从可变向量中删除元素?
How to remove element from mutable vector?
问:
我知道如何创建可变向量:
(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"))
但这行不通。如何从可变向量中删除元素?
编辑: 集合实际上不一定是矢量的。我找到了集合的解决方案,但如果有人会建议矢量的解决方案,我会等待。
答:
2赞
leetwinski
5/4/2016
#1
你的错误是你把 arg 传递给函数,而它实际上接受一个谓词。在你的情况下,这个会起作用(虽然不正确,但制作一个列表而不是一个向量):"test"
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"} %)) ()
评论
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"))
评论