Clojure中的奇怪订单

时间:2016-02-26 05:26:09

标签: clojure set

所以,我正试图通过勇敢的Clojure工作。第三个练习包括创建一个map函数,但它不是返回一个列表,而是返回一个set。好的,我去了:

(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)})))))

然后发生了一些奇怪的事情。功能有用,有点。但是订单全部搞砸了。我知道数学中的数组顺序是无关紧要的,但我不能不知道为什么会发生这种情况:

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}

它不仅具有身份功能。

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

这里发生了什么?

2 个答案:

答案 0 :(得分:4)

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

> (println #{ 1 2 3 4 5 } )
#{1 4 3 2 5}

文字集语法#{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}

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

答案 1 :(得分:2)

默认情况下,集合是无序的。因此,您的结果很好,它们包含正确的元素。一般来说,对于集合来说并不重要。