ClojureDocs

Nav

Namespaces

sort

clojure.core

Available since 1.0 (source)
  • (sort coll)
  • (sort comp coll)
Returns a sorted sequence of the items in coll. If no comparator is
supplied, uses compare.  comparator must implement
java.util.Comparator.  Guaranteed to be stable: equal elements will
not be reordered.  If coll is a Java array, it will be modified.  To
avoid this, sort a copy of the array.
7 Examples
user=> (sort [3 1 2 4])
(1 2 3 4)

user=> (sort > (vals {:foo 5, :bar 2, :baz 10}))
(10 5 2)

;; do not do this, use sort-by instead because it handles calling the fn (e.g last) and compare for you.
user=> (sort #(compare (last %1) (last %2)) {:b 1 :c 3 :a  2})
([:b 1] [:a 2] [:c 3])

;; like this:
user=> (sort-by last {:b 1 :c 3 :a 2})
([:b 1] [:a 2] [:c 3])
;; make a struct 'goods'. it assumes that every goods has
;; its id number and price.
(defstruct goods :id :price)

;; generate data.
(def data (map #(struct goods %1 %2)
	       (shuffle (range 0 10)) (shuffle
				       (into (range 100 500 100)
					     (range 100 500 100)))))

(defn comp-goods-price
  "a compare function by :price of the struct 'goods.' the sort order 
   is superior to the lower price and if the price is same, it is 
   superior to the lower id."
  [el1 el2]
  (or  (< (:price el1) (:price el2))
       (and (= (:price el1) (:price el2))(< (:id el1) (:id el2)))))

user=> data
({:id 1, :price 300} {:id 6, :price 100} {:id 3, :price 100} {:id 4, :price 400} {:id 0, :price 300} {:id 2, :price 200} {:id 5, :price 200} {:id 8, :price 400})
user=> (sort comp-goods-price data)
({:id 3, :price 100} {:id 6, :price 100} {:id 2, :price 200} {:id 5, :price 200} {:id 0, :price 300} {:id 1, :price 300} {:id 4, :price 400} {:id 8, :price 400})
user=> (sort-by :price < data) ; compare this with the above.
({:id 6, :price 100} {:id 3, :price 100} {:id 2, :price 200} {:id 5, :price 200} {:id 1, :price 300} {:id 0, :price 300} {:id 4, :price 400} {:id 8, :price 400})


;; Warning: You can sort a Java array and get back a sorted immutable Clojure
;; data structure, but it will also change the input Java array, by sorting it.
;; Copy the array before sorting if you want to avoid this.

user=> (def x (to-array [32 11]))
#'user/x

user=> (seq x)
(32 11)

user=> (def y (sort x))
#'user/y

;; Return sorted sequence
user=> y
(11 32)

user=> (class y)
clojure.lang.ArraySeq

;; but also modifies x, because it used the array to do the sorting.
user=> (seq x)
(11 32)

;; One way to avoid this is copying the array before sorting:
user=> (def y (sort (aclone x)))
#'user/y
;; Sorting with > only works for numbers, whereas sort
;; also works for other types such as vectors.
;; To sort any data in reverse (descending) order,
;; use a negated comparator:

user=> (sort (comp - compare) [[1 0] [0 0] [0 3] [2 1]])
([2 1] [1 0] [0 3] [0 0])

;; There are subtle cases where negating a comparator can give the wrong sort order.
;; See this article for details, and a more robust suggestion of reversing the
;; order of arguments given to the comparator:
;; https://clojure.org/guides/comparators

user=> (sort #(compare %2 %1) [[1 0] [0 0] [0 3] [2 1]])
([2 1] [1 0] [0 3] [0 0])
;; Reverse the collection

user=> (sort #(compare %2 %1) '(:a :b :c :d))
(:d :c :b :a)
(def data [{:v 12, :a 10} {:v 21, :a 113} {:v 1, :a 2} {:v 12, :a 223} {:v 100, :a 23} {:v 1, :a 113}])

(defn multi-comp
  ([fns a b]
    (multi-comp fns < a b))
  ([[f & others :as fns] order a b]
    (if (seq fns)
      (let [result (compare (f a) (f b))
            f-result (if (= order >) (* -1 result) result)]
        (if (= 0 f-result)
          (recur others order a b)
          f-result))
      0)))

(sort #(multi-comp [:a :v] > %1 %2) data)
;;=> ({:v 12, :a 223} {:v 21, :a 113} {:v 1, :a 113} {:v 100, :a 23} {:v 12, :a 10} {:v 1, :a 2}) 

(sort #(multi-comp [:a :v] < %1 %2) data)
;;=> ({:v 1, :a 2} {:v 12, :a 10} {:v 100, :a 23} {:v 1, :a 113} {:v 21, :a 113} {:v 12, :a 223})
;; Sort strings into ordered character lists

user=> (sort "alphabet!321") 
(\! \1 \2 \3 \a \a \b \e \h \l \p \t)

user=> (sort "안녕하세요") 
(\녕 \세 \안 \요 \하)

user=> (sort "花间一壶酒,独酌无相亲。") 
(\。 \一 \亲 \壶 \无 \独 \相 \花 \酌 \酒 \间 \,)
See Also

Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (k...

Added by morphling

Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than',...

Added by jafingerhut
0 Notes
No notes for sort