Added list(). Enable using function literals with find_first_match().

This commit is contained in:
Garth Minette 2021-04-06 17:03:18 -07:00
parent 2b78f82063
commit f07f5b53c1

View file

@ -200,6 +200,24 @@ function list_tail(list, from=1) =
list;
// Function: list()
// Topics: List Handling, Type Conversion
// Usage:
// list = list(l)
// Description:
// Expands a range into a full list. If given a list, returns it verbatim.
// If given a string, explodes it into a list of single letters.
// Arguments:
// l = The value to expand.
// See Also: scalar_vec3(), force_list(), range(), rangex()
// Example:
// l1 = list([3:2:9]); // Returns: [3,5,7,9]
// l2 = list([3,4,5]); // Returns: [3,4,5]
// l3 = list("Foo"); // Returns: ["F","o","o"]
// l4 = list(23); // Returns: [23]
function list(l) = is_list(l)? l : [for (x=l) x];
// Function: force_list()
// Usage:
// list = force_list(value, <n>, <fill>);
@ -274,20 +292,28 @@ function in_list(val,list,idx) =
// Description:
// Finds the first item in `list` that matches `val`, returning the index.
// Arguments:
// val = The value to search for.
// val = The value to search for. If given a function literal of signature `function (x)`, uses that function to check list items. Returns true for a match.
// list = The list to search through.
// ---
// start = The index to start searching from.
// all = If true, returns a list of all matching item indices.
// eps = The maximum allowed floating point rounding error for numeric comparisons.
function find_first_match(val, list, start=0, all=false, eps=EPSILON) =
all? [for (i=[start:1:len(list)-1]) if(val==list[i] || approx(val, list[i], eps=eps)) i] :
all? [
for (i=[start:1:len(list)-1])
if (
(!is_func(val) && approx(val, list[i], eps=eps)) ||
(is_func(val) && val(list[i]))
) i
] :
__find_first_match(val, list, eps=eps, i=start);
function __find_first_match(val, list, eps, i=0) =
i >= len(list)? undef :
approx(val, list[i], eps=eps)? i :
__find_first_match(val, list, eps=eps, i=i+1);
(
(!is_func(val) && approx(val, list[i], eps=eps)) ||
(is_func(val) && val(list[i]))
)? i : __find_first_match(val, list, eps=eps, i=i+1);
// Function: min_index()