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

发布于 2024-07-23 03:47:17 字数 294 浏览 5 评论 0原文

首先,我假设每个特定于结构的序列都有不同的方式来删除项目:向量可以按索引,列表可以首先删除或最后删除,设置 应该传递要删除的实际项目等。

其次,我假设有一些与结构无关的删除方法; 它们在seq接口上工作。

由于序列在 Clojure 中是不可变的,我怀疑您实际上所做的是制作原始副本的廉价副本,只是没有原始项目。 这意味着列表理解可以用于删除,但我怀疑它会不必要地冗长。

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

First, I assume each structure-specific sequences would have different ways to remove an item: Vectors could be by index, List could be remove first or last, Set should be passing of the actual item to remove, etc.

Second, I assume there are some methods for removal that are structure agnostic; they work on seq interface.

Since sequences are immutable in Clojure, I suspect what you're actually doing is making a cheap copy of the original, only without the original item. This means list comprehension could be used for removal, but I suspect it would be unnecessarily verbose.

Please give some idiomatic examples of the different ways to remove items from Clojure sequences.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千鲤 2024-07-30 03:47:17

没有单一的接口可以从 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 #{:foo} #{:foo :bar})      ; => (:bar)
(remove #{:foo} [:foo :bar])       ; => (:bar)
(remove #{:foo} (list :foo :bar))  ; => (:bar)

这不适用于哈希映射,因为当您迭代映射时,您会得到键/值对。 但这有效:

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

There is no single interface for removing things from all of Clojure's data structure types, possibly because of the different performance characteristics.

(disj #{:foo :bar} :foo)       ; => #{:bar}
(dissoc {:foo 1 :bar 2} :foo)  ; => {:bar 2}
(pop [:bar :foo])              ; => [:bar]
(pop (list :foo :bar))         ; => (:bar)

These also work (returning a seq):

(remove #{:foo} #{:foo :bar})      ; => (:bar)
(remove #{:foo} [:foo :bar])       ; => (:bar)
(remove #{:foo} (list :foo :bar))  ; => (:bar)

This doesn't work for hash-maps because when you iterate over a map, you get key/value pairs. But this works:

(remove (fn [[k v]] (#{:foo} k)) {:foo 1 :bar 2})  ; => ([:bar 2])
仙女山的月亮 2024-07-30 03:47:17

请参阅序列的 Clojure 参考filterremove 正是您所寻求的。

Look at the Clojure reference for sequences. filter and remove are what you seek.

风流物 2024-07-30 03:47:17

作为布莱恩·卡珀答案的延伸。 这取决于您将如何处理结果。 如果您将结果传递给想要处理整个数据集(即打印它)的东西,则通常会创建一个 seq 并使用过滤器或删除来延迟解决问题。 另一方面,如果您正在修改数据结构以保存以后的各种用途,那么在其上创建 seq 将失去其有利的更新特性,因此在这种情况下,最好使用特定于该数据结构的更新函数。

As an extension of Brian Carper's answer. It depends on what you will be doing with the result. If you are passing the result to something that wants to work on the entire set of data (ie to print it) It is idiomatic to make a seq and use filter or remove to solve the problem lazily. If on the other hand you are modifying the data structure to save for various later uses then creating a seq on it would loose its favorable update characteristics so in this case its better to use the update function specific to that data structure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文