mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Renamed array_sort() to sort(), added count_true(), simplified any() and all()
This commit is contained in:
parent
6f5a990124
commit
326dbd47d8
1 changed files with 108 additions and 81 deletions
189
math.scad
189
math.scad
|
@ -245,14 +245,53 @@ function sum_of_sines(a, sines) =
|
||||||
function mean(v) = sum(v)/len(v);
|
function mean(v) = sum(v)/len(v);
|
||||||
|
|
||||||
|
|
||||||
// Section: List/Array Operations
|
// Section: Comparisons and Logic
|
||||||
|
|
||||||
// Function: cdr()
|
// Function: compare_vals()
|
||||||
// Status: DEPRECATED, use `slice(list,1,-1)` instead.
|
// Usage:
|
||||||
// Description: Returns all but the first item of a given array.
|
// compare_vals(a, b);
|
||||||
|
// Description:
|
||||||
|
// Compares two values. If types don't match, then
|
||||||
|
// undef < boolean < scalar < string < list
|
||||||
|
// Lists are compared recursively.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// list = The list to get the tail of.
|
// a = First value to compare.
|
||||||
function cdr(list) = len(list)<=1? [] : [for (i=[1:len(list)-1]) list[i]];
|
// b = Second value to compare.
|
||||||
|
function compare_vals(a, b, n=0) =
|
||||||
|
(a == undef && b == undef)? 0 :
|
||||||
|
(a == undef)? -1 :
|
||||||
|
(b == undef)? 1 :
|
||||||
|
(is_boolean(a) && is_boolean(b))? ((a?1:0)-(b?1:0)) :
|
||||||
|
is_boolean(a)? -1 :
|
||||||
|
is_boolean(b)? 1 :
|
||||||
|
(is_scalar(a) && is_scalar(b))? (a-b) :
|
||||||
|
is_scalar(a)? -1 :
|
||||||
|
is_scalar(b)? 1 :
|
||||||
|
(is_str(a) && is_str(b))? ((a<b)? -1 : ((a>b)? 1 : 0)) :
|
||||||
|
is_str(a)? -1 :
|
||||||
|
is_str(b)? 1 :
|
||||||
|
compare_lists(a,b);
|
||||||
|
|
||||||
|
|
||||||
|
// Function: compare_lists()
|
||||||
|
// Usage:
|
||||||
|
// compare_lists(a, b)
|
||||||
|
// Description:
|
||||||
|
// Compare contents of two lists.
|
||||||
|
// Returns <0 if `a`<`b`.
|
||||||
|
// Returns >0 if `a`>`b`.
|
||||||
|
// Returns 0 if `a`==`b`.
|
||||||
|
// Arguments:
|
||||||
|
// a = First list to compare.
|
||||||
|
// b = Second list to compare.
|
||||||
|
function compare_lists(a, b, n=0) =
|
||||||
|
let (la = len(a), lb = len(b))
|
||||||
|
(la<=n && lb<=n)? 0 :
|
||||||
|
(la<=n)? -1 :
|
||||||
|
(lb<=n)? 1 :
|
||||||
|
let (cmp = compare_vals(a[n], b[n]))
|
||||||
|
(cmp != 0)? cmp :
|
||||||
|
compare_lists(a, b, n+1);
|
||||||
|
|
||||||
|
|
||||||
// Function: any()
|
// Function: any()
|
||||||
|
@ -267,15 +306,13 @@ function cdr(list) = len(list)<=1? [] : [for (i=[1:len(list)-1]) list[i]];
|
||||||
// any([1,5,true]); // Returns true.
|
// any([1,5,true]); // Returns true.
|
||||||
// any([[0,0], [0,0]]); // Returns false.
|
// any([[0,0], [0,0]]); // Returns false.
|
||||||
// any([[0,0], [1,0]]); // Returns true.
|
// any([[0,0], [1,0]]); // Returns true.
|
||||||
function any(l, s=0, e=-1) =
|
function any(l, i=0, succ=false) =
|
||||||
let(
|
(i>=len(l) || succ)? succ :
|
||||||
e = e<0? e+len(l) : e,
|
any(
|
||||||
m = ceil((s+e)/2)
|
l, i=i+1, succ=(
|
||||||
)
|
is_array(l[i])? any(l[i]) :
|
||||||
(e==s)? (
|
!(!l[i])
|
||||||
is_array(l[s])? any(l[s]) : (l[s]? true : false)
|
)
|
||||||
) : (
|
|
||||||
any(l,s,m-1)? true : any(l,m,e)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -292,18 +329,56 @@ function any(l, s=0, e=-1) =
|
||||||
// all([[0,0], [0,0]]); // Returns false.
|
// all([[0,0], [0,0]]); // Returns false.
|
||||||
// all([[0,0], [1,0]]); // Returns false.
|
// all([[0,0], [1,0]]); // Returns false.
|
||||||
// all([[1,1], [1,1]]); // Returns true.
|
// all([[1,1], [1,1]]); // Returns true.
|
||||||
function all(l, s=0, e=-1) =
|
function all(l, i=0, fail=false) =
|
||||||
let(
|
(i>=len(l) || fail)? (!fail) :
|
||||||
e = e<0? e+len(l) : e,
|
all(
|
||||||
m = ceil((s+e)/2)
|
l, i=i+1, fail=(
|
||||||
)
|
is_array(l[i])? !all(l[i]) :
|
||||||
(e==s)? (
|
!l[i]
|
||||||
is_array(l[s])? all(l[s]) : (l[s]? true : false)
|
)
|
||||||
) : (
|
|
||||||
(!all(l,s,m-1))? false : all(l,m,e)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Function: count_true()
|
||||||
|
// Usage:
|
||||||
|
// count_true(l)
|
||||||
|
// Description:
|
||||||
|
// Returns the number of items in `l` that evaluate as true.
|
||||||
|
// If `l` is a lists of lists, this is applied recursively to each
|
||||||
|
// sublist. Returns the total count of items that evaluate as true
|
||||||
|
// in all recursive sublists.
|
||||||
|
// Arguments:
|
||||||
|
// l = The list to test for true items.
|
||||||
|
// nmax = If given, stop counting if `nmax` items evaluate as true.
|
||||||
|
// Example:
|
||||||
|
// count_true([0,false,undef]); // Returns 0.
|
||||||
|
// count_true([1,false,undef]); // Returns 1.
|
||||||
|
// count_true([1,5,false]); // Returns 2.
|
||||||
|
// count_true([1,5,true]); // Returns 3.
|
||||||
|
// count_true([[0,0], [0,0]]); // Returns 0.
|
||||||
|
// count_true([[0,0], [1,0]]); // Returns 1.
|
||||||
|
// count_true([[1,1], [1,1]]); // Returns 4.
|
||||||
|
// count_true([[1,1], [1,1]], nmax=3); // Returns 3.
|
||||||
|
function count_true(l, nmax=undef, i=0, cnt=0) =
|
||||||
|
(i>=len(l) || (nmax!=undef && cnt>=nmax))? cnt :
|
||||||
|
count_true(
|
||||||
|
l=l, nmax=nmax, i=i+1, cnt=cnt+(
|
||||||
|
is_array(l[i])? count_true(l[i], nmax=nmax-cnt) :
|
||||||
|
(l[i]? 1 : 0)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Section: List/Array Operations
|
||||||
|
|
||||||
|
// Function: cdr()
|
||||||
|
// Status: DEPRECATED, use `slice(list,1,-1)` instead.
|
||||||
|
// Description: Returns all but the first item of a given array.
|
||||||
|
// Arguments:
|
||||||
|
// list = The list to get the tail of.
|
||||||
|
function cdr(list) = len(list)<=1? [] : [for (i=[1:len(list)-1]) list[i]];
|
||||||
|
|
||||||
|
|
||||||
// Function: in_list()
|
// Function: in_list()
|
||||||
// Description: Returns true if value `x` is in list `l`.
|
// Description: Returns true if value `x` is in list `l`.
|
||||||
|
@ -530,57 +605,9 @@ function array_group(v, cnt=2, dflt=0) = [for (i = [0:cnt:len(v)-1]) [for (j = [
|
||||||
function flatten(l) = [for (a = l) for (b = a) b];
|
function flatten(l) = [for (a = l) for (b = a) b];
|
||||||
|
|
||||||
|
|
||||||
// Function: compare_lists()
|
// Function: sort()
|
||||||
// Usage:
|
// Usage:
|
||||||
// compare_lists(a, b)
|
// sort(arr, [idx])
|
||||||
// Description:
|
|
||||||
// Compare contents of two lists.
|
|
||||||
// Returns <0 if `a`<`b`.
|
|
||||||
// Returns >0 if `a`>`b`.
|
|
||||||
// Returns 0 if `a`==`b`.
|
|
||||||
// Arguments:
|
|
||||||
// a = First list to compare.
|
|
||||||
// b = Second list to compare.
|
|
||||||
function compare_lists(a, b, n=0) =
|
|
||||||
let (la = len(a), lb = len(b))
|
|
||||||
(la<=n && lb<=n)? 0 :
|
|
||||||
(la<=n)? -1 :
|
|
||||||
(lb<=n)? 1 :
|
|
||||||
let (cmp = compare_vals(a[n], b[n]))
|
|
||||||
(cmp != 0)? cmp :
|
|
||||||
compare_lists(a, b, n+1);
|
|
||||||
|
|
||||||
|
|
||||||
// Function: compare_vals()
|
|
||||||
// Usage:
|
|
||||||
// compare_vals(a, b);
|
|
||||||
// Description:
|
|
||||||
// Compares two values. If types don't match, then
|
|
||||||
// undef < boolean < scalar < string < list
|
|
||||||
// Lists are compared recursively.
|
|
||||||
// Arguments:
|
|
||||||
// a = First value to compare.
|
|
||||||
// b = Second value to compare.
|
|
||||||
function compare_vals(a, b, n=0) =
|
|
||||||
(a == undef && b == undef)? 0 :
|
|
||||||
(a == undef)? -1 :
|
|
||||||
(b == undef)? 1 :
|
|
||||||
(is_boolean(a) && is_boolean(b))? ((a?1:0)-(b?1:0)) :
|
|
||||||
is_boolean(a)? -1 :
|
|
||||||
is_boolean(b)? 1 :
|
|
||||||
(is_scalar(a) && is_scalar(b))? (a-b) :
|
|
||||||
is_scalar(a)? -1 :
|
|
||||||
is_scalar(b)? 1 :
|
|
||||||
(is_str(a) && is_str(b))? ((a<b)? -1 : ((a>b)? 1 : 0)) :
|
|
||||||
is_str(a)? -1 :
|
|
||||||
is_str(b)? 1 :
|
|
||||||
compare_lists(a,b);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function: array_sort()
|
|
||||||
// Usage:
|
|
||||||
// array_sort(arr, [idx])
|
|
||||||
// Description:
|
// Description:
|
||||||
// Sorts the given list using `compare_vals()`.
|
// Sorts the given list using `compare_vals()`.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
@ -588,8 +615,8 @@ function compare_vals(a, b, n=0) =
|
||||||
// idx = If given, the index, range, or list of indices of sublist items to compare.
|
// idx = If given, the index, range, or list of indices of sublist items to compare.
|
||||||
// Example:
|
// Example:
|
||||||
// l = [45,2,16,37,8,3,9,23,89,12,34];
|
// l = [45,2,16,37,8,3,9,23,89,12,34];
|
||||||
// sorted = array_sort(l); // Returns [2,3,8,9,12,16,23,34,37,45,89]
|
// sorted = sort(l); // Returns [2,3,8,9,12,16,23,34,37,45,89]
|
||||||
function array_sort(arr, idx=undef) =
|
function sort(arr, idx=undef) =
|
||||||
(len(arr)<=1) ? arr :
|
(len(arr)<=1) ? arr :
|
||||||
let(
|
let(
|
||||||
pivot = arr[floor(len(arr)/2)],
|
pivot = arr[floor(len(arr)/2)],
|
||||||
|
@ -603,20 +630,20 @@ function array_sort(arr, idx=undef) =
|
||||||
equal = [ for (i = [0:len(arr)-1]) if (compare[i] ==0) arr[i] ],
|
equal = [ for (i = [0:len(arr)-1]) if (compare[i] ==0) arr[i] ],
|
||||||
greater = [ for (i = [0:len(arr)-1]) if (compare[i] > 0) arr[i] ]
|
greater = [ for (i = [0:len(arr)-1]) if (compare[i] > 0) arr[i] ]
|
||||||
)
|
)
|
||||||
concat(array_sort(lesser,idx), equal, array_sort(greater,idx));
|
concat(sort(lesser,idx), equal, sort(greater,idx));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function: array_unique()
|
// Function: unique()
|
||||||
// Usage:
|
// Usage:
|
||||||
// array_unique(arr);
|
// unique(arr);
|
||||||
// Description:
|
// Description:
|
||||||
// Returns a sorted list with all repeated items removed.
|
// Returns a sorted list with all repeated items removed.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// arr = The list to uniquify.
|
// arr = The list to uniquify.
|
||||||
function array_unique(arr) =
|
function unique(arr) =
|
||||||
len(arr)<=1? arr : let(
|
len(arr)<=1? arr : let(
|
||||||
sorted = array_sort(arr)
|
sorted = sort(arr)
|
||||||
) [
|
) [
|
||||||
for (i=[0:len(sorted)-1])
|
for (i=[0:len(sorted)-1])
|
||||||
if (i==0 || (sorted[i] != sorted[i-1]))
|
if (i==0 || (sorted[i] != sorted[i-1]))
|
||||||
|
|
Loading…
Reference in a new issue