Fix slice() bug when index is off the end, doc fix

This commit is contained in:
Adrian Mariano 2023-01-28 11:53:02 -05:00
parent ea3e720493
commit d8dccc0005
3 changed files with 17 additions and 7 deletions

View file

@ -229,8 +229,9 @@ function select(list, start, end) =
// list = slice(list, s, e); // list = slice(list, s, e);
// Description: // Description:
// Returns a slice of a list, from the first position `s` up to and including the last position `e`. // Returns a slice of a list, from the first position `s` up to and including the last position `e`.
// The first item in the list is at index 0. Negative indexes are counted back from the end. // The first item in the list is at index 0. Negative indexes are counted back from the end, with
// An index of -1 refers to the last list item. // -1 referring to the last list item. If `s` is after `e` then the empty list is returned.
// If an index is off the start/end of the list it will refer to the list start/end.
// Arguments: // Arguments:
// list = The list to get the slice of. // list = The list to get the slice of.
// start = The index of the first item to return. Default: 0 // start = The index of the first item to return. Default: 0
@ -243,6 +244,8 @@ function select(list, start, end) =
// d = slice([3,4,5,6,7,8,9], 5); // Returns [8,9] // d = slice([3,4,5,6,7,8,9], 5); // Returns [8,9]
// e = slice([3,4,5,6,7,8,9], 2, -2); // Returns [5,6,7,8] // e = slice([3,4,5,6,7,8,9], 2, -2); // Returns [5,6,7,8]
// f = slice([3,4,5,6,7,8,9], 4, 3; // Returns [] // f = slice([3,4,5,6,7,8,9], 4, 3; // Returns []
// g = slice([3,4,5], 1, 5; // Returns [4,5]
// h = slice([3,4,5], 5, 7); // Returns []
function slice(list,start=0,end=-1) = function slice(list,start=0,end=-1) =
assert(is_list(list)) assert(is_list(list))
assert(is_int(start)) assert(is_int(start))
@ -250,11 +253,10 @@ function slice(list,start=0,end=-1) =
!list? [] : !list? [] :
let( let(
l = len(list), l = len(list),
start = constrain(start + (start<0? l : 0), 0, l-1), start = start+(start<0 ? l : 0),
end = constrain(end + (end<0? l : 0), 0, l-1) end = end + (end<0? l : 0)
) )
[if (end>=start) for (i=[start:1:end]) list[i]]; [if (start<=end && end>=0 && start<=l) for (i=[max(start,0):1:min(end,l-1)]) list[i]];
// Function: last() // Function: last()
// Usage: // Usage:

View file

@ -139,7 +139,7 @@
// a vertex duplicating method on one side and a resampling method on the other side, then // a vertex duplicating method on one side and a resampling method on the other side, then
// `refine` must be set so that the resulting number of vertices matches the number that is // `refine` must be set so that the resulting number of vertices matches the number that is
// used for the resampled profiles. The best way to avoid confusion is to ensure that the // used for the resampled profiles. The best way to avoid confusion is to ensure that the
// profiles connected by "direct" or "realign" all have the same number of points and at the // profiles connected by "direct" or "reindex" all have the same number of points and at the
// transition, the refined number of points matches. // transition, the refined number of points matches.
// . // .
// Arguments: // Arguments:

View file

@ -37,6 +37,14 @@ module test_slice() {
assert(slice(l, 3, 3) == [6]); assert(slice(l, 3, 3) == [6]);
assert(slice(l, 4) == [7,8,9]); assert(slice(l, 4) == [7,8,9]);
assert(slice(l, -2) == [8,9]); assert(slice(l, -2) == [8,9]);
assert(slice(l,-10,-8) == []);
assert(slice(l,10,12) == []);
assert(slice(l,12,10) == []);
assert(slice(l,4,12) == [7,8,9]);
assert(slice(l,-10,2) == [3,4,5]);
assert(slice(l,-10,-4) == [3,4,5,6]);
assert(slice(l,-1,1) == []);
assert(slice(l,5,4) == []);
} }
test_slice(); test_slice();