forked from Mirror/wren
Added List.sort(comp) to List module (#802)
This commit is contained in:
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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
9
test/core/list/sort.wren
Normal 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.
|
||||||
Reference in New Issue
Block a user