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

欢迎!请参阅 关于 页面获取更多有关此功能的信息。

+11
序列
重新标记

令我惊讶的是,我发现当在集合上调用 distinct 时,它会抛出一个异常,例如。
(distinct #{1 2 3})

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

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

distinct 的文档字符串声明
> 返回一个元素唯一并按顺序排列的迭代结果。

由于 (coll? #{1 2 3}) => true,这使得用户难以理解。

关于它在 math.combinatorics 中的出现已有一些讨论:此处此处,但没有真正做出决定。

我建议将 distinct 设计为可以接受任何可序列化的集合。

2 答案

+2

集合本身已经唯一 - 为什么还要对其调用 distinct?

如果你有一个函数接受一个集合,你不一定知道它是一个集合还是向量,对吧?除非你在函数体内测试它。
我将重写:"我建议distinct内部应该支持集合"为:"distinct应接受任何可序列化的集合"。
Stan是对的,我的函数接受所有集合,并且重要的是在保留顺序的同时获取不同的值。我已经用Alex的建议修改了我的问题,感谢你们两人。
我想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`类型上工作。
...