Hello!
I was recently surprised by Clojure’s sorting behavior when sorting tuples, which seems to depend on length:
(sort [[1 :a] [2] [3 :b] [0 :c :c]])
;; => ([2] [1 :a] [3 :b] [0 :c :c])
I was expecting what Python does:
>>> sorted([(1, 'a'), (2,), (3, 'b'), (0, 'c', 'c')])
[(0, 'c', 'c'), (1, 'a'), (2,), (3, 'b')]
Anyone know why this is the case? Is there a rationale I haven’t found?
Thanks!
Teodor
Edit: found Clojure - Comparators Guide (by @andy.fingerhut ). Still gladly welcoming comments.
Edit 2: Relevant excerpt from the docs:
- vectors are sorted from fewest elements to most elements, with lexicographic ordering among equal length vectors.
Edit 3: I guess Edit 2 answers my question. New question: I’m now searching for a simple way to do lexical sorting by elements, ie. the Python behavior.
Edit 4: The docs contained the outline for lexical sorting. Here’s an adapted example:
(defn cmp-vec-lexi
[x y]
(let [x-len (count x)
y-len (count y)
len (min x-len y-len)]
(loop [i 0]
(if (== i len)
;; If all elements 0..(len-1) are same, shorter vector comes
;; first.
(compare x-len y-len)
(let [c (compare (x i) (y i))]
(if (zero? c)
(recur (inc i))
c))))))
(sort-by identity cmp-vec-lexi [[1 :a] [2] [3 :b] [0 :c :c]])
;; => ([0 :c :c] [1 :a] [2] [3 :b])