mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Improved compare_vals() and compare_lists() for heterogenous types.
This commit is contained in:
parent
94c2378136
commit
56b41b487b
2 changed files with 97 additions and 48 deletions
42
math.scad
42
math.scad
|
@ -366,49 +366,49 @@ function determinant(M) =
|
|||
// Section: Comparisons and Logic
|
||||
|
||||
|
||||
function _type_num(x) =
|
||||
is_undef(x)? 0 :
|
||||
is_bool(x)? 1 :
|
||||
is_num(x)? 2 :
|
||||
is_string(x)? 3 :
|
||||
is_list(x)? 4 : 5;
|
||||
|
||||
|
||||
// Function: compare_vals()
|
||||
// Usage:
|
||||
// compare_vals(a, b);
|
||||
// Description:
|
||||
// Compares two values. Lists are compared recursively.
|
||||
// Results are undefined if the two values are not of similar types.
|
||||
// If types are not the same, then undef < bool < num < str < list < range.
|
||||
// Arguments:
|
||||
// a = First value to compare.
|
||||
// b = Second value to compare.
|
||||
function compare_vals(a, b) =
|
||||
(a==b)? 0 :
|
||||
(a==undef)? -1 :
|
||||
(b==undef)? 1 :
|
||||
((a==[] || a=="" || a[0]!=undef) && (b==[] || b=="" || b[0]!=undef))? (
|
||||
compare_lists(a, b)
|
||||
) : (a<b)? -1 :
|
||||
(a>b)? 1 : 0;
|
||||
let(t1=_type_num(a), t2=_type_num(b)) (t1!=t2)? (t1-t2) :
|
||||
is_list(a)? compare_lists(a,b) :
|
||||
(a<b)? -1 : (a>b)? 1 : 0;
|
||||
|
||||
|
||||
// Function: compare_lists()
|
||||
// Usage:
|
||||
// compare_lists(a, b)
|
||||
// Description:
|
||||
// Compare contents of two lists.
|
||||
// Compare contents of two lists using `compare_vals()`.
|
||||
// Returns <0 if `a`<`b`.
|
||||
// Returns 0 if `a`==`b`.
|
||||
// Returns >0 if `a`>`b`.
|
||||
// Results are undefined if elements are not of similar types.
|
||||
// Arguments:
|
||||
// a = First list to compare.
|
||||
// b = Second list to compare.
|
||||
function compare_lists(a, b, n=0) =
|
||||
let(
|
||||
// This curious construction enables tail recursion optimization.
|
||||
cmp = (a==b)? 0 :
|
||||
(len(a)<=n)? -1 :
|
||||
(len(b)<=n)? 1 :
|
||||
(a==a[n] || b==b[n])? (
|
||||
a<b? -1 : a>b? 1 : 0
|
||||
) : compare_vals(a[n], b[n])
|
||||
)
|
||||
(cmp != 0 || a==b)? cmp :
|
||||
compare_lists(a, b, n+1);
|
||||
function compare_lists(a, b) =
|
||||
a==b? 0 : let(
|
||||
cmps = [
|
||||
for(i=[0:1:min(len(a),len(b))-1]) let(
|
||||
cmp = compare_vals(a[i],b[i])
|
||||
) if(cmp!=0) cmp
|
||||
]
|
||||
) cmps==[]? (len(a)-len(b)) : cmps[0];
|
||||
|
||||
|
||||
// Function: any()
|
||||
|
|
|
@ -282,52 +282,101 @@ test_mean();
|
|||
|
||||
|
||||
module test_compare_vals() {
|
||||
assert(compare_vals(-10,0) == -1);
|
||||
assert(compare_vals(10,0) == 1);
|
||||
assert(compare_vals(-10,0) < 0);
|
||||
assert(compare_vals(10,0) > 0);
|
||||
assert(compare_vals(10,10) == 0);
|
||||
|
||||
assert(compare_vals("abc","abcd") == -1);
|
||||
assert(compare_vals("abcd","abc") == 1);
|
||||
assert(compare_vals("abc","abcd") < 0);
|
||||
assert(compare_vals("abcd","abc") > 0);
|
||||
assert(compare_vals("abcd","abcd") == 0);
|
||||
|
||||
assert(compare_vals(false,false) == 0);
|
||||
assert(compare_vals(true,false) == 1);
|
||||
assert(compare_vals(false,true) == -1);
|
||||
assert(compare_vals(true,false) > 0);
|
||||
assert(compare_vals(false,true) < 0);
|
||||
assert(compare_vals(true,true) == 0);
|
||||
|
||||
assert(compare_vals([2,3,4], [2,3,4,5]) == -1);
|
||||
assert(compare_vals([2,3,4], [2,3,4,5]) < 0);
|
||||
assert(compare_vals([2,3,4,5], [2,3,4,5]) == 0);
|
||||
assert(compare_vals([2,3,4,5], [2,3,4]) == 1);
|
||||
assert(compare_vals([2,3,4,5], [2,3,5,5]) == -1);
|
||||
assert(compare_vals([[2,3,4,5]], [[2,3,5,5]]) == -1);
|
||||
assert(compare_vals([2,3,4,5], [2,3,4]) > 0);
|
||||
assert(compare_vals([2,3,4,5], [2,3,5,5]) < 0);
|
||||
assert(compare_vals([[2,3,4,5]], [[2,3,5,5]]) < 0);
|
||||
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4], [3,4,5]]) == 0);
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4,5], [3,4,5]]) == -1);
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4], [3,4,5,6]]) == -1);
|
||||
assert(compare_vals([[2,3,4,5],[3,4,5]], [[2,3,4], [3,4,5]]) == 1);
|
||||
assert(compare_vals([[2,3,4],[3,4,5,6]], [[2,3,4], [3,4,5]]) == 1);
|
||||
assert(compare_vals([[2,3,4],[3,5,5]], [[2,3,4], [3,4,5]]) == 1);
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4], [3,5,5]]) == -1);
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4,5], [3,4,5]]) < 0);
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4], [3,4,5,6]]) < 0);
|
||||
assert(compare_vals([[2,3,4,5],[3,4,5]], [[2,3,4], [3,4,5]]) > 0);
|
||||
assert(compare_vals([[2,3,4],[3,4,5,6]], [[2,3,4], [3,4,5]]) > 0);
|
||||
assert(compare_vals([[2,3,4],[3,5,5]], [[2,3,4], [3,4,5]]) > 0);
|
||||
assert(compare_vals([[2,3,4],[3,4,5]], [[2,3,4], [3,5,5]]) < 0);
|
||||
|
||||
assert(compare_vals(undef, undef) == 0);
|
||||
assert(compare_vals(undef, true) < 0);
|
||||
assert(compare_vals(undef, 0) < 0);
|
||||
assert(compare_vals(undef, "foo") < 0);
|
||||
assert(compare_vals(undef, [2,3,4]) < 0);
|
||||
assert(compare_vals(undef, [0:3]) < 0);
|
||||
|
||||
assert(compare_vals(true, undef) > 0);
|
||||
assert(compare_vals(true, true) == 0);
|
||||
assert(compare_vals(true, 0) < 0);
|
||||
assert(compare_vals(true, "foo") < 0);
|
||||
assert(compare_vals(true, [2,3,4]) < 0);
|
||||
assert(compare_vals(true, [0:3]) < 0);
|
||||
|
||||
assert(compare_vals(0, undef) > 0);
|
||||
assert(compare_vals(0, true) > 0);
|
||||
assert(compare_vals(0, 0) == 0);
|
||||
assert(compare_vals(0, "foo") < 0);
|
||||
assert(compare_vals(0, [2,3,4]) < 0);
|
||||
assert(compare_vals(0, [0:3]) < 0);
|
||||
|
||||
assert(compare_vals(1, undef) > 0);
|
||||
assert(compare_vals(1, true) > 0);
|
||||
assert(compare_vals(1, 1) == 0);
|
||||
assert(compare_vals(1, "foo") < 0);
|
||||
assert(compare_vals(1, [2,3,4]) < 0);
|
||||
assert(compare_vals(1, [0:3]) < 0);
|
||||
|
||||
assert(compare_vals("foo", undef) > 0);
|
||||
assert(compare_vals("foo", true) > 0);
|
||||
assert(compare_vals("foo", 1) > 0);
|
||||
assert(compare_vals("foo", "foo") == 0);
|
||||
assert(compare_vals("foo", [2,3,4]) < 0);
|
||||
assert(compare_vals("foo", [0:3]) < 0);
|
||||
|
||||
assert(compare_vals([2,3,4], undef) > 0);
|
||||
assert(compare_vals([2,3,4], true) > 0);
|
||||
assert(compare_vals([2,3,4], 1) > 0);
|
||||
assert(compare_vals([2,3,4], "foo") > 0);
|
||||
assert(compare_vals([2,3,4], [2,3,4]) == 0);
|
||||
assert(compare_vals([2,3,4], [0:3]) < 0);
|
||||
|
||||
assert(compare_vals([0:3], undef) > 0);
|
||||
assert(compare_vals([0:3], true) > 0);
|
||||
assert(compare_vals([0:3], 1) > 0);
|
||||
assert(compare_vals([0:3], "foo") > 0);
|
||||
assert(compare_vals([0:3], [2,3,4]) > 0);
|
||||
assert(compare_vals([0:3], [0:3]) == 0);
|
||||
}
|
||||
test_compare_vals();
|
||||
|
||||
|
||||
module test_compare_lists() {
|
||||
assert(compare_lists([2,3,4], [2,3,4,5]) == -1);
|
||||
assert(compare_lists([2,3,4], [2,3,4,5]) < 0);
|
||||
assert(compare_lists([2,3,4,5], [2,3,4,5]) == 0);
|
||||
assert(compare_lists([2,3,4,5], [2,3,4]) == 1);
|
||||
assert(compare_lists([2,3,4,5], [2,3,5,5]) == -1);
|
||||
assert(compare_lists([2,3,4,5], [2,3,4]) > 0);
|
||||
assert(compare_lists([2,3,4,5], [2,3,5,5]) < 0);
|
||||
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4], [3,4,5]]) == 0);
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4,5], [3,4,5]]) == -1);
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4], [3,4,5,6]]) == -1);
|
||||
assert(compare_lists([[2,3,4,5],[3,4,5]], [[2,3,4], [3,4,5]]) == 1);
|
||||
assert(compare_lists([[2,3,4],[3,4,5,6]], [[2,3,4], [3,4,5]]) == 1);
|
||||
assert(compare_lists([[2,3,4],[3,5,5]], [[2,3,4], [3,4,5]]) == 1);
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4], [3,5,5]]) == -1);
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4,5], [3,4,5]]) < 0);
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4], [3,4,5,6]]) < 0);
|
||||
assert(compare_lists([[2,3,4,5],[3,4,5]], [[2,3,4], [3,4,5]]) > 0);
|
||||
assert(compare_lists([[2,3,4],[3,4,5,6]], [[2,3,4], [3,4,5]]) > 0);
|
||||
assert(compare_lists([[2,3,4],[3,5,5]], [[2,3,4], [3,4,5]]) > 0);
|
||||
assert(compare_lists([[2,3,4],[3,4,5]], [[2,3,4], [3,5,5]]) < 0);
|
||||
|
||||
assert(compare_lists("cat", "bat") == 1);
|
||||
assert(compare_lists(["cat"], ["bat"]) == 1);
|
||||
assert(compare_lists("cat", "bat") > 0);
|
||||
assert(compare_lists(["cat"], ["bat"]) > 0);
|
||||
}
|
||||
test_compare_lists();
|
||||
|
||||
|
|
Loading…
Reference in a new issue