2024 Clojure 状态调查! 中分享你的想法。

欢迎!请查看 关于 页面以获取更多关于如何操作的信息。

+11
序列
重标记

令我意外的是,distinct 在对一个集合调用时会抛出异常,例如。
(distinct #{1 2 3})

一种解决方案是先调用 seq 对集合: (distinct (seq #{1 2 3}))

然而,这似乎是多余的仪式,因为我想到的其他所有序列运算符 - mapkeepreducefirstsome 等都将接受集合。

distinct 的文档字符串中声明
> 返回一个不包含重复元素的 coll 元素的惰性序列。

因为 (coll? #{1 2 3}) => true,这对于用户理解来说很困惑。

关于这个主题已经在 math.combinatorics 这里和一些其他地方进行了讨论,但没有做出任何真正的决定。

我建议 distinct 应该接受任何可序列化的 coll。

2 答案

+2

集合已经是唯一的了 - 你为什么要对它调用 distinct?

如果你有一个函数接受一组,你不一定知道它是一个集合或向量,对吗?除非你在函数体内测试它。
我只将 "我建议 distinct 应该在内部支持集合" 改为 "distinct 应该接受任何可迭代的序列"。
Stan 是正确的,我的封装函数接受所有集合,并且在我获取到不同的值同时保持顺序时非常重要。我已经根据你提出的措辞更新了我的问题,感谢你们两位。
我想 distinct 在序列函数中特别不意外地不接收集合。distinct 的步骤函数使用结构化来查看集合中的第一个项目;结构化使用 nth;而 nth 不适用于集合。(nth 的文档字符串也将参数称为“coll”,但列举了允许的具体系列类型。)

我们不需要深入研究只修复 distinct 的利弊,这个问题可以在 nth 本身中得到更深入的处理,从而全班解决这个怪癖。已经,nth 测试了几个情况,最后一个情况是顺序对象的 O(n) 时间。为什么不添加另一个情况来覆盖可序列化的对象呢?与 contains?不同,nth 对暴力搜索没有疑问。并且,因为 nth 是结构化工具,这不会非常暴力(结构化通常只会查找几个前成员)并且好处将是广泛的。
这不是一个好主意。nth是用于索引或有序集合的,而集合则不是。更好的做法是让distinct对其输入进行排序,生成一个集合的稳定逻辑列表视图,类似于其他所有序列函数。
0票数
这应该已经修复,因为翻译器版本工作得很好,因此表现不同。

```
(into [] (distinct) #{:a :b})
=> [:b :a]
```

常规的distinct实现选择使用解构,这需要nth。

是的,我们还有一些工具函数,它们接收`coll`并期望在所有类型的`coll`上工作。
...