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.
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])
(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 "花间一壶酒,独酌无相亲。") (\。 \一 \亲 \壶 \无 \独 \相 \花 \酌 \酒 \间 \,)
Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (k...
Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than',...
sort