如何从Clojure中的序列中删除项目?

如何从Clojure中的序列中删除项目?,clojure,sequences,Clojure,Sequences,首先,我假设每个特定于结构的序列都有不同的删除项的方法:向量可以是索引,列表可以是第一个或最后一个删除,集合应该是要删除的实际项的传递,等等 第二,我假设有一些去除的方法是结构不可知的;他们在seq接口上工作 因为序列在Clojure中是不可变的,所以我怀疑你实际上是在制作原作的廉价副本,只是没有原作。这意味着可以使用列表理解来删除,但我怀疑这将是不必要的冗长 请给出一些惯用的例子,说明从Clojure序列中删除项目的不同方法。请查看过滤器和删除是您需要的。没有一个接口可以从Clojure的所有

首先,我假设每个特定于结构的序列都有不同的删除项的方法:向量可以是索引,列表可以是第一个或最后一个删除,集合应该是要删除的实际项的传递,等等

第二,我假设有一些去除的方法是结构不可知的;他们在seq接口上工作

因为序列在Clojure中是不可变的,所以我怀疑你实际上是在制作原作的廉价副本,只是没有原作。这意味着可以使用列表理解来删除,但我怀疑这将是不必要的冗长


请给出一些惯用的例子,说明从Clojure序列中删除项目的不同方法。

请查看<代码>过滤器和删除是您需要的。

没有一个接口可以从Clojure的所有数据结构类型中删除内容,可能是因为性能特征不同

(disj #{:foo :bar} :foo)       ; => #{:bar}
(dissoc {:foo 1 :bar 2} :foo)  ; => {:bar 2}
(pop [:bar :foo])              ; => [:bar]
(pop (list :foo :bar))         ; => (:bar)
这些也起作用(返回一个
seq
):

这对哈希映射不起作用,因为当您在映射上迭代时,会得到键/值对。但这是可行的:

(remove (fn [[k v]] (#{:foo} k)) {:foo 1 :bar 2})  ; => ([:bar 2])

作为Brian Carper答案的延伸。这取决于你将如何处理结果。如果您要将结果传递给希望处理整个数据集(即打印它)的对象,那么制作一个seq并使用filter或remove惰性地解决问题是一种习惯做法。另一方面,如果要修改数据结构以保存以供以后各种使用,则在其上创建seq将失去其有利的更新特性,因此在这种情况下,最好使用该数据结构特有的更新功能

谢谢,布莱恩,这就是我要找的。您提到的subvec似乎与文档不符:“返回vector中从开始(包含)到结束(独占)的项的持久向量。如果未提供结束,则默认为(计数向量)。”您的意思是可以连接两个subvec调用以忽略“已删除”项吗?是的,这就是我的意思。事后看来,它可能过于笨拙甚至无法考虑。我会把它从邮件中删除。值得一提的是(对于向量),因为它在O(1)时间内运行。这是对所有使用原语作为函数的人的警告。当项目为布尔值时,此操作失败。您必须完整地写出函数:
(remove#(contains?#{false}%)[true-false])
。(我确实遇到过这种情况。)严格来说,上面的答案并非在所有情况下都是正确的。如果有人想知道如何只删除最后一项:但最后一项是你的功能。
(remove (fn [[k v]] (#{:foo} k)) {:foo 1 :bar 2})  ; => ([:bar 2])