【问题标题】:How to remove element from mutable vector?如何从可变向量中删除元素?
【发布时间】:2016-05-04 15:30:10
【问题描述】:

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

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

【问题讨论】:

    标签: vector clojure mutable


    【解决方案1】:

    您的错误是您将 "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"} %))
      ()
      

    【讨论】:

    • 你能确认我的理解吗?使用该构造,我们实际上不会修改集合,而是更改引用 @my-vector 以指向新创建的可变向量。我说的对吗?
    • 其实没有可变的向量,只有可变的references。您的向量始终保持不可变,而引用指向新构建的向量(clojure 的数据模型使其成为一种非常便宜的操作)
    • 好吧,其实也有可变结构,例如瞬态,(clojure.org/reference/transients) 但它是更高级的优化点,所以要小心处理
    • 所以我做对了。回答你的问题,为什么我使用这样的结构。好吧,这就是我在互联网上可以找到的。我是 Clojure 初学者,尝试创建“可变”集合,但没有真正研究如何去做。问题的构造实际上是在 stackoverflow 上找到的:stackoverflow.com/a/5554870/5026241。原子是我所遵循的书中的下一章,但我需要在周五完成我的任务:)。
    • 那么我可能会建议你花几个小时阅读一些适当的语言介绍,这样会更有效率,然后阅读一些关于 SO 的随机帖子)braveclojure.com/clojure-for-the-brave-and-true
    【解决方案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))
    =>#{}
    

    【讨论】:

    • 我想你在最后一行是指disj(dosync (alter my-set disj "test"))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 2020-05-22
    • 1970-01-01
    相关资源
    最近更新 更多