diff --git a/src/util/_impl/_sorted_impl.scad b/src/util/_impl/_sorted_impl.scad index 7d63d9b8..74f5a235 100644 --- a/src/util/_impl/_sorted_impl.scad +++ b/src/util/_impl/_sorted_impl.scad @@ -7,16 +7,24 @@ function before_after(lt, pivot, less, leng, before = [], after = [], j = 1) = j + 1 ); -function _sorted(lt, less) = +identity = function(elem) elem; + +function elems(lt, elem) = [for(e = lt) elem(e)]; + +function _sorted(lt, less, elem = identity) = let(leng = len(lt)) - leng <= 1 ? lt : - leng == 2 ? !less(lt[1], lt[0]) ? lt : [lt[1], lt[0]] : + leng <= 1 ? elems(lt, elem) : + leng == 2 ? !less(lt[1], lt[0]) ? elems(lt, elem) : elems([lt[1], lt[0]], elem) : let( pivot = lt[0], b_a = before_after(lt, pivot, less, leng) ) - [each _sorted(b_a[0], less), pivot, each _sorted(b_a[1], less)]; + [each _sorted(b_a[0], less, elem), elem(pivot), each _sorted(b_a[1], less, elem)]; function _sorted_default(lt) = _sorted(lt, function(a, b) a < b); -function _sorted_cmp(lt, cmp) = _sorted(lt, function(a, b) cmp(a, b) < 0); \ No newline at end of file +function _sorted_cmp(lt, cmp) = _sorted(lt, function(a, b) cmp(a, b) < 0); + +function _sorted_key(lt, key) = + let(key_elem_lt = [for(elem = lt) [key(elem), elem]]) + _sorted(key_elem_lt, function(a, b) a[0] < b[0], function(elem) elem[1]); \ No newline at end of file diff --git a/src/util/sorted.scad b/src/util/sorted.scad index f79d7085..85231b49 100644 --- a/src/util/sorted.scad +++ b/src/util/sorted.scad @@ -10,5 +10,7 @@ use <_impl/_sorted_impl.scad>; -function sorted(lt, cmp = undef) = - is_undef(cmp) ? _sorted_default(lt) : _sorted_cmp(lt, cmp); \ No newline at end of file +function sorted(lt, cmp = undef, key = undef) = + !is_undef(cmp) ? _sorted_cmp(lt, cmp) : + !is_undef(key) ? _sorted_key(lt, key) : + _sorted_default(lt); \ No newline at end of file diff --git a/test/util/test_sorted.scad b/test/util/test_sorted.scad index 3f22a3be..d1790ef6 100644 --- a/test/util/test_sorted.scad +++ b/test/util/test_sorted.scad @@ -21,6 +21,11 @@ module test_sorted() { descending = function(e1, e2) e2 - e1; assert(sorted([2, 1, 3, 5, 4], ascending) == [1, 2, 3, 4, 5]); assert(sorted([2, 1, 3, 5, 4], descending) == [5, 4, 3, 2, 1]); + + assert( + [[2, 0, 0], [5, 0, 0], [7, 0, 0], [9, 0, 0], [10, 0, 0]] == + sorted([[10, 0, 0], [5, 0, 0], [7, 0, 0], [2, 0, 0], [9, 0, 0]], key = function(elem) elem.x) + ); } test_sorted();