1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-11 09:14:29 +02:00

by supports a function literal

This commit is contained in:
Justin Lin
2021-02-07 12:13:32 +08:00
parent ea9be0180c
commit 968c668cee
5 changed files with 36 additions and 17 deletions

View File

@@ -139,7 +139,7 @@ These examples incubate dotSCAD and dotSCAD refactors these examples. See [examp
- [util/parse_number](https://openhome.cc/eGossip/OpenSCAD/lib2x-parse_number.html)
- [util/reverse](https://openhome.cc/eGossip/OpenSCAD/lib2x-reverse.html)
- [util/slice](https://openhome.cc/eGossip/OpenSCAD/lib2x-slice.html)
- [util/sort](https://openhome.cc/eGossip/OpenSCAD/lib2x-sort.html)
- [util/sort](https://openhome.cc/eGossip/OpenSCAD/lib3x-sort.html)
- [util/rand](https://openhome.cc/eGossip/OpenSCAD/lib2x-rand.html)
- [util/fibseq](https://openhome.cc/eGossip/OpenSCAD/lib2x-fibseq.html)
- [util/bsearch](https://openhome.cc/eGossip/OpenSCAD/lib2x-bsearch.html)

View File

@@ -2,14 +2,12 @@
Sorts the elements of a list in ascending order. The list is a list-of-list construct, such as `[[a0, a1, a2...], [b0, b1, b2,...], [c0, c1, c2,...],...]`. When sorting, the function looks only at one index position of each sublist.
From dotSCAD 2.3, when `by` is `"vt"`, it will sort points by zyx (from the last index to the first one).
**Since:** 2.0
## Parameters
- `lt` : The original list.
- `by` : Can be `"x"``"y"``"z"`, `"idx"` (Default) or `"vt"`.
- `by` : Can be `"x"``"y"``"z"`, or `"idx"` (Default). `"vt"`. From dotSCAD 2.3, when `by` is `"vt"`, it will sort points by zyx (from the last index to the first one). From dotSCAD 3.0, `by` supports a function literal that compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
- `idx` : When `by` is `"idx"`, the value of `idx` is used. The Default value is 0.
## Examples
@@ -29,4 +27,9 @@ From dotSCAD 2.3, when `by` is `"vt"`, it will sort points by zyx (from the last
assert(
[[0, 2, 0], [0, 5, 0], [0, 7, 0], [0, 9, 0], [0, 10, 0]] ==
sort([[0, 10, 0], [0, 5, 0], [0, 7, 0], [0, 2, 0], [0, 9, 0]], by = "idx", idx = 1)
);
);
ascending = function(e1, e2) e1 - e2;
descending = function(e1, e2) e2 - e1;
assert(sort([2, 1, 3, 5, 4], by = ascending) == [1, 2, 3, 4, 5]);
assert(sort([2, 1, 3, 5, 4], by = descending) == [5, 4, 3, 2, 1]);

View File

@@ -25,4 +25,14 @@ function _sort_by(lt, by, idx) =
dict = [["x", 0], ["y", 1], ["z", 2], ["i", idx]],
i = dict[search(by == "idx" ? "i" : by, dict)[0]][1]
)
_sort_by_idx(lt, i);
_sort_by_idx(lt, i);
function _sort_by_comp(lt, comp) =
let(leng = len(lt))
leng <= 1 ? lt :
let(
pivot = lt[0],
before = [for(j = 1; j < leng; j = j + 1) if(comp(lt[j], pivot) < 0) lt[j]],
after = [for(j = 1; j < leng; j = j + 1) if(comp(lt[j], pivot) >= 0) lt[j]]
)
concat(_sort_by_comp(before, comp), [pivot], _sort_by_comp(after, comp));

View File

@@ -4,12 +4,13 @@
* @copyright Justin Lin, 2019
* @license https://opensource.org/licenses/lgpl-3.0.html
*
* @see https://openhome.cc/eGossip/OpenSCAD/lib2x-sort.html
* @see https://openhome.cc/eGossip/OpenSCAD/lib3x-sort.html
*
**/
use <_impl/_sort_impl.scad>;
function sort(lt, by = "idx", idx = 0) =
is_function(by) ? _sort_by_comp(lt, by) : // support function literal
by == "vt" ? _vt_sort(lt) : // for example, sort by zyx for a list of points
_sort_by(lt, by, idx);

View File

@@ -4,20 +4,25 @@ use <util/sort.scad>;
module test_sort() {
echo("==== test_sort ====");
assertEqualPoints(
[[2, 0, 0], [5, 0, 0], [7, 0, 0], [9, 0, 0], [10, 0, 0]],
assert(
[[2, 0, 0], [5, 0, 0], [7, 0, 0], [9, 0, 0], [10, 0, 0]] ==
sort([[10, 0, 0], [5, 0, 0], [7, 0, 0], [2, 0, 0], [9, 0, 0]])
);
assert(
[[2, 0, 0], [5, 0, 0], [7, 0, 0], [9, 0, 0], [10, 0, 0]] ==
sort([[10, 0, 0], [5, 0, 0], [7, 0, 0], [2, 0, 0], [9, 0, 0]], by = "x")
);
assertEqualPoints(
[[2, 0, 0], [5, 0, 0], [7, 0, 0], [9, 0, 0], [10, 0, 0]],
sort([[10, 0, 0], [5, 0, 0], [7, 0, 0], [2, 0, 0], [9, 0, 0]], by = "idx", idx = 0)
);
assertEqualPoints(
[[0, 2, 0], [0, 5, 0], [0, 7, 0], [0, 9, 0], [0, 10, 0]],
sort([[0, 10, 0], [0, 5, 0], [0, 7, 0], [0, 2, 0], [0, 9, 0]], by = "y")
assert(
[[0, 2, 0], [0, 5, 0], [0, 7, 0], [0, 9, 0], [0, 10, 0]] ==
sort([[0, 10, 0], [0, 5, 0], [0, 7, 0], [0, 2, 0], [0, 9, 0]], by = "idx", idx = 1)
);
ascending = function(e1, e2) e1 - e2;
descending = function(e1, e2) e2 - e1;
assert(sort([2, 1, 3, 5, 4], by = ascending) == [1, 2, 3, 4, 5]);
assert(sort([2, 1, 3, 5, 4], by = descending) == [5, 4, 3, 2, 1]);
}
test_sort();