1
0
forked from Mirror/wren

Added List.sort(comp) to List module (#802)

This commit is contained in:
Mat Mariani
2020-12-03 14:59:07 -05:00
committed by GitHub
parent 08d2fa3821
commit 3d5e68fc01
4 changed files with 102 additions and 0 deletions

View File

@ -94,6 +94,29 @@ System.print(["a", "b", "c"].removeAt(1)) //> b
It is a runtime error if the index is not an integer or is out of bounds. It is a runtime error if the index is not an integer or is out of bounds.
### **sort**(), **sort**(comparer)
Sorts the elements of a list in-place; altering the list. The default sort is implemented using the quicksort algorithm.
<pre class="snippet">
var list = [4, 1, 3, 2].sort()
System.print(list) //> [1, 2, 3, 4]
</pre>
A comparison function `comparer` can be provided to customise the element sorting. The comparison function must return a boolean value specifying the order in which elements should appear in the list.
The comparison function accepts two arguments `a` and `b`, two values to compare, and must return a boolean indicating the inequality between the arguments. If the function returns true, the first argument `a` will appear before the second `b` in the sorted results.
A compare function like `{|a, b| true }` will always put `a` before `b`. The default compare function is `{|a, b| a < b }`.
<pre class="snippet">
var list = [9, 6, 8, 7]
list.sort {|a, b| a < b}
System.print(list) //> [6, 7, 8, 9]
</pre>
It is a runtime error if `comparer` is not a function.
### **[**index**]** operator ### **[**index**]** operator
Gets the element at `index`. If `index` is negative, it counts backwards from Gets the element at `index`. If `index` is negative, it counts backwards from

View File

@ -323,6 +323,41 @@ class List is Sequence {
return other return other
} }
sort() { sort {|low, high| low < high } }
sort(comparer) {
if (!(comparer is Fn)) {
Fiber.abort("Comparer must be a function.")
}
quicksort_(0, count - 1, comparer)
return this
}
quicksort_(low, high, comparer) {
if (low < high) {
var p = partition_(low, high, comparer)
quicksort_(low, p - 1, comparer)
quicksort_(p + 1, high, comparer)
}
}
partition_(low, high, comparer) {
var p = this[high]
var i = low - 1
for (j in low..(high-1)) {
if (comparer.call(this[j], p)) {
i = i + 1
var t = this[i]
this[i] = this[j]
this[j] = t
}
}
var t = this[i+1]
this[i+1] = this[high]
this[high] = t
return i+1
}
toString { "[%(join(", "))]" } toString { "[%(join(", "))]" }
+(other) { +(other) {

View File

@ -325,6 +325,41 @@ static const char* coreModuleSource =
" return other\n" " return other\n"
" }\n" " }\n"
"\n" "\n"
" sort() { sort {|low, high| low < high } }\n"
"\n"
" sort(comparer) {\n"
" if (!(comparer is Fn)) {\n"
" Fiber.abort(\"Comparer must be a function.\")\n"
" }\n"
" quicksort_(0, count - 1, comparer)\n"
" return this\n"
" }\n"
"\n"
" quicksort_(low, high, comparer) {\n"
" if (low < high) {\n"
" var p = partition_(low, high, comparer)\n"
" quicksort_(low, p - 1, comparer)\n"
" quicksort_(p + 1, high, comparer)\n"
" }\n"
" }\n"
"\n"
" partition_(low, high, comparer) {\n"
" var p = this[high]\n"
" var i = low - 1\n"
" for (j in low..(high-1)) {\n"
" if (comparer.call(this[j], p)) { \n"
" i = i + 1\n"
" var t = this[i]\n"
" this[i] = this[j]\n"
" this[j] = t\n"
" }\n"
" }\n"
" var t = this[i+1]\n"
" this[i+1] = this[high]\n"
" this[high] = t\n"
" return i+1\n"
" }\n"
"\n"
" toString { \"[%(join(\", \"))]\" }\n" " toString { \"[%(join(\", \"))]\" }\n"
"\n" "\n"
" +(other) {\n" " +(other) {\n"

9
test/core/list/sort.wren Normal file
View File

@ -0,0 +1,9 @@
System.print([4, 1, 3, 2].sort()) // expect: [1, 2, 3, 4]
var l = [10, 7, 8, 9, 1, 5]
l.sort{|a, b| a < b }
System.print(l) // expect: [1, 5, 7, 8, 9, 10]
l.sort{|a, b| a > b }
System.print(l) // expect: [10, 9, 8, 7, 5, 1]
[10, 7, 8, 9, 1, 5].sort(3) // expect runtime error: Comparer must be a function.