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

欢迎!有关如何使用本站的信息,请参阅关于页面。

+11
序列
重新标记为

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

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

但是,这似乎是一种不必要的仪式,因为我想到的其他所有序列操作符,如 map、keep、reduce、first、some 等,都可以接受集合。

distinct 的文档字符串指出
> 返回一个不需要重复元素的集合的惰性序列。

因为 (coll? #{1 2 3}) => true 这可能会使用户感到困惑。

关于此问题的一些相关讨论可以在 这里这里 找到,但没有做出任何实际的决定。

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

2 答案

+2

集合已经是唯一的了 - 你为什么还要在集合上调用 distinct 呢?

如果你有一个接受集合的函数,你并不一定知道它是集合还是向量,对吗?除非你在函数体内测试它。
我将重新表述“我建议distinct应该支持内部集合”这句话,仅将其改为“distinct应该接受任何可迭代的集合”。
Stan是正确的,我的封装函数接受所有集合,并且我需要得到不同的值同时保留顺序。我已经根据你提出的措辞Alex更新了我的问题,谢谢你们两个。
我想distinct在序列函数中是例外,它不接受集合。distinct的步函数使用解构来查看集合中的第一个元素;解构使用nth;而nth不支持集合。(nth的文档字符串同样把参数称为"coll",但列出了允许的实体类型。)

与其深入思考只修复distinct的利弊,不如更深入地在这个nth自身上解决问题,这样可以更广泛地解决这个问题。已经,nth测试了几个情况,最后一个是对于序列类型O(n)时间。为什么不添加另一个案例来覆盖seq'able事物?与contains?不同,nth并不害怕粗略的手段。因为nth是解构的工具,所以它不会太粗鲁(解构通常只获取少数几个第一个成员),而且好处将非常广泛。
by
这不是一个好主意。nth 是用于索引或有序集合的,而集合既不是索引的也不是有序的。更好的答案是让 distinct 将输入转换为序列,生成一个稳定的逻辑视图,类似于所有其他序列函数。
0 投票
by
by
这个问题应该得到解决,因为 transcducer 版本工作正常,并且表现不同。

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

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

是的,我们还有一些期望在所有类型的 coll 上工作的 util 函数。
...