store/[org.clojure/clojure "1.8.0"] clj::clojure.core/compare

Community Documentation

Edit

Arities

[x y] -> Integer

Docs

Compares x to y as if via Java x.compareTo(y) and returns an integer n.

  • n < 0 if x is "less than" y
  • n = 0 if x is "equal to" y
  • n > 0 if x is "greater than" y
  • Numbers: increasing numeric order, returning 0 if two numbers are numerically equal by clj::clojure.core/==, even if clj::clojure.core/= is false.
  • Strings, Symbols, Keywords: lexicographic order (aka dictionary order) by their representation as sequences of UTF-16 code units. This is alphabetical order (case-sensitive) for strings restricted to the ASCII subset.
  • Vectors: shortest-to-longest, with lexicographic ordering among equal length vectors.
  • nil: can be compared to all values above, and is considered less than anything else.
  • All Java types implementing the Comparable interface such as characters, booleans, File, URI, and UUID are compared via their .compareTo methods.

Notes

An exception will be thrown if x and y are "too different" and cannot be compared. Integers, Longs, and Doubles can be compared to each other, but not strings to keywords or keywords to symbols. lists, sequences, sets, and maps also cannot be compared.

Implementation detail: Clojure Refs can also be sorted using compare. They are sorted in the order they were created.

Source

(defn compare
  "Comparator. Returns a negative number, zero, or a positive number
  when x is logically 'less than', 'equal to', or 'greater than'
  y. Same as Java x.compareTo(y) except it also works for nil, and
  compares numbers and collections in a type-independent manner. x
  must implement Comparable"
  {
   :inline (fn [x y] `(. clojure.lang.Util compare ~x ~y))
   :added "1.0"}
  [x y] (. clojure.lang.Util (compare x y)))

Example 1

Edit
;; Vectors are sorted by their length first, from shortest to longest,
;; then lexicographically among equal-length vectors.

(sort [[1 2] [1 -5] [10000] [4 -1 20] [3 2 5]])
;; => ([10000] [1 -5] [1 2] [3 2 5] [4 -1 20])

Example 2

Edit
;; Symbols are sorted by their representation as strings, sorting first
;; by their namespace name, and if they are in the same namespace, then
;; by their name.  If no namespace is included, those symbols will be
;; sorted before any symbol with a namespace.  Keywords are sorted
;; similarly to symbols.

(def sset2 (sorted-set 'user/foo 'clojure.core/pprint 'bar
                       'clojure.core/apply 'user/zz))
;; => #'user/sset2

sset2
;; => #{bar clojure.core/apply clojure.core/pprint user/foo user/zz}

(def smap1 (sorted-map :map-key 10, :amp [3 2 1],
                       :blammo "kaboom"))
;; => #'user/smap1

smap1
;; => {:amp [3 2 1], :blammo "kaboom", :map-key 10}

Example 3

Edit
;; An exception will be thrown if you call compare with different types (any
;; numeric types above can be compared to each other, but not to a non-numeric
;; type). An exception will also be thrown if you use compare on a list, set,
;; map, or any other type not mentioned above. You must implement your own
;; comparator if you wish to sort such values.  See [Comparators in
;; Clojure][Comparators] for examples of comparators that can do this.

(sort [5 "a"])
;; => ClassCastException java.lang.Long cannot be cast to java.lang.String  java.lang.String.compareTo (String.java:108)

(sort [:foo 'bar])
;; => ClassCastException clojure.lang.Keyword cannot be cast to clojure.lang.Symbol  clojure.lang.Symbol.compareTo (Symbol.java:106)

(sort [#{1 2} {2 4}])
;; => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable  clojure.lang.Util.compare (Util.java:153)

(sort [{:a 1 :b 3} {:c -2 :d 4}])
;; => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable  clojure.lang.Util.compare (Util.java:153)

Example 4

Edit
;; various examples
;; comparing vectors of different sizes does not work as you may expect
;; the longer vector is always "greater" regardless of contents 

(compare [0 1 2] [0 1 2])
;; => 0

(compare [1 2 3] [0 1 2 3])
;; => -1

(compare [0 1 2] [3 4])
;; => 1

(compare nil [1 2 3])
;; => -1

(compare [1 2 3] nil)
;; => 1

(compare "abc" "def")
;; => -3

(compare "abc" "abd")
;; => -1

Uses on crossclj