1
0
mirror of https://github.com/janet-lang/janet synced 2025-01-24 06:06:52 +00:00

Add sort-by and sorted-by.

This commit is contained in:
Calvin Rose 2020-04-09 20:42:49 -05:00
parent e6d4e729fb
commit 02f17bd4e4
3 changed files with 45 additions and 26 deletions

View File

@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Unreleased - ??? ## Unreleased - ???
- Add `sort-by` and `sorted-by` to core.
- Support UTF-8 escapes in strings via `\uXXXX` or `\UXXXXXX`. - Support UTF-8 escapes in strings via `\uXXXX` or `\UXXXXXX`.
- Add `math/erf` - Add `math/erf`
- Add `math/erfc` - Add `math/erfc`

View File

@ -656,41 +656,54 @@
### ###
### ###
(def sort (defn- sort-part
"(sort xs [, by])\n\nSort an array in-place. Uses quick-sort and is not a stable sort." [a lo hi by]
(do (def pivot (in a hi))
(var i lo)
(for j lo hi
(def aj (in a j))
(when (by aj pivot)
(def ai (in a i))
(set (a i) aj)
(set (a j) ai)
(++ i)))
(set (a hi) (in a i))
(set (a i) pivot)
i)
(defn part (defn- sort-help
[a lo hi by] [a lo hi by]
(def pivot (in a hi)) (when (> hi lo)
(var i lo) (def piv (sort-part a lo hi by))
(for j lo hi (sort-help a lo (- piv 1) by)
(def aj (in a j)) (sort-help a (+ piv 1) hi by))
(when (by aj pivot) a)
(def ai (in a i))
(set (a i) aj)
(set (a j) ai)
(++ i)))
(set (a hi) (in a i))
(set (a i) pivot)
i)
(defn sort-help (defn sort
[a lo hi by] "Sort an array in-place. Uses quick-sort and is not a stable sort."
(when (> hi lo) [a &opt by]
(def piv (part a lo hi by)) (sort-help a 0 (- (length a) 1) (or by <)))
(sort-help a lo (- piv 1) by)
(sort-help a (+ piv 1) hi by))
a)
(fn sort [a &opt by] (put _env 'sort-part nil)
(sort-help a 0 (- (length a) 1) (or by <))))) (put _env 'sort-help nil)
(defn sort-by
"Returns a new sorted array that compares elements by invoking
a function on each element and comparing the result with <."
[f ind]
(sort ind (fn [x y] (< (f x) (f y)))))
(defn sorted (defn sorted
"Returns a new sorted array without modifying the old one." "Returns a new sorted array without modifying the old one."
[ind &opt by] [ind &opt by]
(sort (array/slice ind) by)) (sort (array/slice ind) by))
(defn sorted-by
"Returns a new sorted array that compares elements by invoking
a function on each element and comparing the result with <."
[f ind]
(sorted ind (fn [x y] (< (f x) (f y)))))
(defn reduce (defn reduce
"Reduce, also know as fold-left in many languages, transforms "Reduce, also know as fold-left in many languages, transforms
an indexed type (array, tuple) with a function to produce a value." an indexed type (array, tuple) with a function to produce a value."

View File

@ -254,6 +254,11 @@
(assert (apply <= (merge @[1 3 5] @[2 4 6 6 6 9])) "merge sort merge 3") (assert (apply <= (merge @[1 3 5] @[2 4 6 6 6 9])) "merge sort merge 3")
(assert (apply <= (merge '(1 3 5) @[2 4 6 6 6 9])) "merge sort merge 4") (assert (apply <= (merge '(1 3 5) @[2 4 6 6 6 9])) "merge sort merge 4")
(assert (deep= @[1 2 3 4 5] (sort @[5 3 4 1 2])) "sort 1")
(assert (deep= @[{:a 1} {:a 4} {:a 7}] (sort-by |($ :a) @[{:a 4} {:a 7} {:a 1}])) "sort 2")
(assert (deep= @[1 2 3 4 5] (sorted [5 3 4 1 2])) "sort 3")
(assert (deep= @[{:a 1} {:a 4} {:a 7}] (sorted-by |($ :a) [{:a 4} {:a 7} {:a 1}])) "sort 4")
# Gensym tests # Gensym tests
(assert (not= (gensym) (gensym)) "two gensyms not equal") (assert (not= (gensym) (gensym)) "two gensyms not equal")