mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Added list(). Enable using function literals with find_first_match().
This commit is contained in:
parent
2b78f82063
commit
f07f5b53c1
1 changed files with 33 additions and 7 deletions
40
arrays.scad
40
arrays.scad
|
@ -200,6 +200,24 @@ function list_tail(list, from=1) =
|
||||||
list;
|
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()
|
// Function: force_list()
|
||||||
// Usage:
|
// Usage:
|
||||||
// list = force_list(value, <n>, <fill>);
|
// list = force_list(value, <n>, <fill>);
|
||||||
|
@ -274,20 +292,28 @@ function in_list(val,list,idx) =
|
||||||
// Description:
|
// Description:
|
||||||
// Finds the first item in `list` that matches `val`, returning the index.
|
// Finds the first item in `list` that matches `val`, returning the index.
|
||||||
// Arguments:
|
// 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.
|
// list = The list to search through.
|
||||||
// ---
|
// ---
|
||||||
// start = The index to start searching from.
|
// start = The index to start searching from.
|
||||||
// all = If true, returns a list of all matching item indices.
|
// all = If true, returns a list of all matching item indices.
|
||||||
// eps = The maximum allowed floating point rounding error for numeric comparisons.
|
// eps = The maximum allowed floating point rounding error for numeric comparisons.
|
||||||
function find_first_match(val, list, start=0, all=false, eps=EPSILON) =
|
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);
|
__find_first_match(val, list, eps=eps, i=start);
|
||||||
|
|
||||||
function __find_first_match(val, list, eps, i=0) =
|
function __find_first_match(val, list, eps, i=0) =
|
||||||
i >= len(list)? undef :
|
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()
|
// Function: min_index()
|
||||||
|
@ -425,7 +451,7 @@ function range(n, s=0, e, step) =
|
||||||
let( step = (n!=undef && e!=undef)? (e-s)/(n-1) : default(step,1) )
|
let( step = (n!=undef && e!=undef)? (e-s)/(n-1) : default(step,1) )
|
||||||
is_undef(e)
|
is_undef(e)
|
||||||
? assert( is_consistent([s, step]), "Incompatible data.")
|
? assert( is_consistent([s, step]), "Incompatible data.")
|
||||||
[for (i=[0:1:n-1]) s+step*i ]
|
[for (i=[0:1:n-1]) s+step*i]
|
||||||
: assert( is_vector([s,step,e]), "Start `s`, step `step` and end `e` must be numbers.")
|
: assert( is_vector([s,step,e]), "Start `s`, step `step` and end `e` must be numbers.")
|
||||||
[for (v=[s:step:e]) v] ;
|
[for (v=[s:step:e]) v] ;
|
||||||
|
|
||||||
|
@ -468,10 +494,10 @@ function rangex(n, s=0, e, step) =
|
||||||
let( step = (n!=undef && e!=undef)? (e-s)/n : default(step,1) )
|
let( step = (n!=undef && e!=undef)? (e-s)/n : default(step,1) )
|
||||||
is_undef(e)
|
is_undef(e)
|
||||||
? assert( is_consistent([s, step]), "Incompatible data.")
|
? assert( is_consistent([s, step]), "Incompatible data.")
|
||||||
[for (i=[0:1:n-1]) s+step*i ]
|
[for (i=[0:1:n-1]) s+step*i]
|
||||||
: assert( is_vector([s,step,e]), "Start `s`, step `step` and end `e` must be numbers.")
|
: assert( is_vector([s,step,e]), "Start `s`, step `step` and end `e` must be numbers.")
|
||||||
let(steps=floor((e-s)/step+0.5))
|
let(steps=floor((e-s)/step+0.5))
|
||||||
[for (i=[0:1:steps-1]) s+step*i ];
|
[for (i=[0:1:steps-1]) s+step*i];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue