Clojure 集合中的奇怪顺序

joa*_*yra 0 clojure set

所以,我正在尝试通过 Brave Clojure 工作。第三个练习是创建一个 map 函数,但它应该返回一个集合而不是返回一个列表。好的,那我走了:

(defn mapset
  [f lst]
  (loop [[head & remaining] lst
         final-set #{}]
    (if (empty? remaining)
      (into final-set #{(f head)})
      (recur remaining
             (into final-set #{(f head)})))))
Run Code Online (Sandbox Code Playgroud)

但随后发生了一些奇怪的事情。该功能有效,有点。但是顺序在集合中全部搞砸了。我知道集合中的数学顺序无关紧要,但我不禁想知道为什么会发生这种情况:

clojure-noob.core=> (mapset identity [1])
#{1}
clojure-noob.core=> (mapset identity [1 2])
#{1 2}
clojure-noob.core=> (mapset identity [1 2 3])
#{1 3 2}
clojure-noob.core=> (mapset identity [1 2 3 4])
#{1 4 3 2}
clojure-noob.core=> (mapset identity [1 2 3 4 5])
#{1 4 3 2 5}
clojure-noob.core=> (mapset identity [1 2 3 4 5 6])
#{1 4 6 3 2 5}
Run Code Online (Sandbox Code Playgroud)

它也不仅仅是身份功能。

clojure-noob.core=> (mapset inc [1 2 3])
#{4 3 2}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么事?

Ala*_*son 5

正如 ymonad 所说,Clojure 集是“随机”排序的:

> (println #{ 1 2 3 4 5 } )
#{1 4 3 2 5}
Run Code Online (Sandbox Code Playgroud)

文字集语法#{1 2 3 4 5}只是(hash-set ...). 您可以获得如图所示的排序集:

> (hash-set 1 2 3 4 5 6)
#{1 4 6 3 2 5}
> (sorted-set 1 2 3 4 5 6)
#{1 2 3 4 5 6}
> (into (sorted-set) #{1 2 3 4 5 6} )
#{1 2 3 4 5 6}
Run Code Online (Sandbox Code Playgroud)

在最后一个例子中,我们使用into将常规集合中的元素添加到一个空的sorted-set