为什么Clojure的分组依据不能始终保持秩序?

Why does clojure's group-by not always maintain order?

为什么(分组身份(范围1 50))返回类似

的结果

{32 [32],1 [1],33 [33],2 [2],34 [34],3 [3],35 [35] ...

与多线程相关吗?有什么办法解决吗?

...它是否违反合同?

Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll.


尝试在REPL中输入(type (group-by identity (range 1 50)))。您可以看到结果实际上是一个哈希映射(类别clojure.lang.PersistentHashMap)。这意味着它是无序的:原则上,REPL可以按键/值对的任何顺序输出打印的地图文字。

其打印方式的实际原因与Clojure哈希表的实现有关-就数据结构而言,它实际上是一棵宽树,每个节点最多可以有32个孩子(因此最初的32个孩子在您的输出中;回想一下,经常引用Clojure向量和映射来查找成本为O(log32N))。这篇博客文章有一个很好的总结。

不,它不违反group-by的约定。该合同仅指定地图值元素的顺序,而不指定地图本身的顺序。