mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-01-16 21:58:27 +01:00
Added closed option to deduplicate(). Fixed inconsistent indentation.
This commit is contained in:
parent
5abc7db530
commit
959781d6fe
164
arrays.scad
164
arrays.scad
@ -158,15 +158,20 @@ function reverse(list) = [ for (i = [len(list)-1 : -1 : 0]) list[i] ];
|
||||
// This is different from `unique()` in that the list is *not* sorted.
|
||||
// Arguments:
|
||||
// list = The list to deduplicate.
|
||||
// closed = If true, drops trailing items if they match the first list item.
|
||||
// eps = The maximum difference to allow between numbers or vectors.
|
||||
// Examples:
|
||||
// deduplicate([8,3,4,4,4,8,2,3,3,7]); // Returns: [8,3,4,8,2,3,7]
|
||||
// deduplicate([8,3,4,4,4,8,2,3,3,8,8]); // Returns: [8,3,4,8,2,3,8]
|
||||
// deduplicate(closed=true, [8,3,4,4,4,8,2,3,3,8,8]); // Returns: [8,3,4,8,2,3]
|
||||
// deduplicate("Hello"); // Returns: ["H","e","l","o"]
|
||||
// deduplicate([[3,4],[7,2],[7,1.99],[1,4]],eps=0.1); // Returns: [[3,4],[7,2],[1,4]]
|
||||
function deduplicate(list, eps=EPSILON) =
|
||||
(is_num(list[0]) || is_vector(list[0]))?
|
||||
[for (i=[0:1:len(list)-1]) if (!approx(list[i], list[i+1], eps)) list[i]] :
|
||||
[for (i=[0:1:len(list)-1]) if (list[i] != list[i+1]) list[i]];
|
||||
function deduplicate(list, closed=false, eps=EPSILON) =
|
||||
let(
|
||||
l = len(list),
|
||||
end = l-(closed?0:1)
|
||||
) (is_num(list[0]) || is_vector(list[0]))?
|
||||
[for (i=[0:1:l-1]) if (i==end || !approx(list[i], list[(i+1)%l], eps)) list[i]] :
|
||||
[for (i=[0:1:l-1]) if (i==end || list[i] != list[(i+1)%l]) list[i]];
|
||||
|
||||
|
||||
// Function: list_set()
|
||||
@ -283,7 +288,9 @@ function list_bset(indexset, valuelist, dflt=0) =
|
||||
// list_increasing(list)
|
||||
// Description:
|
||||
// Returns true if the list is (non-strictly) increasing
|
||||
function list_increasing(list,ind=0) = ind < len(list)-1 && list[ind]<=list[ind+1] ? list_increasing(list,ind+1) :
|
||||
function list_increasing(list,ind=0) =
|
||||
(ind < len(list)-1 && list[ind]<=list[ind+1])?
|
||||
list_increasing(list,ind+1) :
|
||||
(ind>=len(list)-1 ? true : false);
|
||||
|
||||
|
||||
@ -291,7 +298,9 @@ function list_increasing(list,ind=0) = ind < len(list)-1 && list[ind]<=list[ind+
|
||||
// Usage:
|
||||
// list_increasing(list)
|
||||
// Description: returns true if the list is (non-strictly) decreasing
|
||||
function list_decreasing(list,ind=0) = ind < len(list)-1 && list[ind]>=list[ind+1] ? list_increasing(list,ind+1) :
|
||||
function list_decreasing(list,ind=0) =
|
||||
(ind < len(list)-1 && list[ind]>=list[ind+1])?
|
||||
list_increasing(list,ind+1) :
|
||||
(ind>=len(list)-1 ? true : false);
|
||||
|
||||
|
||||
@ -395,70 +404,119 @@ function shuffle(list) =
|
||||
|
||||
// Sort a vector of scalar values
|
||||
function _sort_scalars(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
let( pivot = arr[floor(len(arr)/2)],
|
||||
len(arr)<=1 ? arr : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y < pivot) y ],
|
||||
equal = [ for (y = arr) if (y == pivot) y ],
|
||||
greater = [ for (y = arr) if (y > pivot) y ]
|
||||
)
|
||||
concat( _sort_scalars(lesser), equal, _sort_scalars(greater) );
|
||||
) concat( _sort_scalars(lesser), equal, _sort_scalars(greater) );
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first entry only of each vector
|
||||
function _sort_vectors1(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
!(len(arr)>0) ? [] :
|
||||
let( pivot = arr[floor(len(arr)/2)],
|
||||
!(len(arr)>0) ? [] : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y[0] < pivot[0]) y ],
|
||||
equal = [ for (y = arr) if (y[0] == pivot[0]) y ],
|
||||
greater = [ for (y = arr) if (y[0] > pivot[0]) y ]
|
||||
)
|
||||
concat( _sort_vectors1(lesser), equal, _sort_vectors1(greater) );
|
||||
) concat( _sort_vectors1(lesser), equal, _sort_vectors1(greater) );
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first two entries of each vector
|
||||
// Lexicographic order, remaining entries of vector ignored
|
||||
function _sort_vectors2(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
!(len(arr)>0) ? [] :
|
||||
let( pivot = arr[floor(len(arr)/2)],
|
||||
!(len(arr)>0) ? [] : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y[0] < pivot[0] || (y[0]==pivot[0] && y[1]<pivot[1])) y ],
|
||||
equal = [ for (y = arr) if (y[0] == pivot[0] && y[1]==pivot[1]) y ],
|
||||
greater = [ for (y = arr) if (y[0] > pivot[0] || (y[0]==pivot[0] && y[1]>pivot[1])) y ]
|
||||
)
|
||||
concat( _sort_vectors2(lesser), equal, _sort_vectors2(greater) );
|
||||
) concat( _sort_vectors2(lesser), equal, _sort_vectors2(greater) );
|
||||
|
||||
// Sort a vector of vectors based on the first three entries of each vector
|
||||
// Lexicographic order, remaining entries of vector ignored
|
||||
function _sort_vectors3(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
let( pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y[0] < pivot[0] ||
|
||||
(y[0]==pivot[0] && (y[1]<pivot[1] ||
|
||||
(y[1]==pivot[1] && y[2]<pivot[2])))) y],
|
||||
equal = [ for (y = arr) if (y[0] == pivot[0] && y[1]== pivot[1] && y[2]==pivot[2]) y ],
|
||||
greater = [ for (y = arr) if (y[0] > pivot[0] ||
|
||||
(y[0]==pivot[0] && (y[1]>pivot[1] ||
|
||||
(y[1]==pivot[1] && y[2]>pivot[2])))) y]
|
||||
len(arr)<=1 ? arr : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [
|
||||
for (y = arr) if (
|
||||
y[0] < pivot[0] || (
|
||||
y[0]==pivot[0] && (
|
||||
y[1]<pivot[1] || (
|
||||
y[1]==pivot[1] &&
|
||||
y[2]<pivot[2]
|
||||
)
|
||||
concat( _sort_vectors3(lesser), equal, _sort_vectors3(greater) );
|
||||
)
|
||||
)
|
||||
) y
|
||||
],
|
||||
equal = [
|
||||
for (y = arr) if (
|
||||
y[0] == pivot[0] && y[1]== pivot[1] && y[2]==pivot[2]
|
||||
) y
|
||||
],
|
||||
greater = [
|
||||
for (y = arr) if (
|
||||
y[0] > pivot[0] || (
|
||||
y[0]==pivot[0] && (
|
||||
y[1]>pivot[1] || (
|
||||
y[1]==pivot[1] &&
|
||||
y[2]>pivot[2]
|
||||
)
|
||||
)
|
||||
)
|
||||
) y
|
||||
]
|
||||
) concat( _sort_vectors3(lesser), equal, _sort_vectors3(greater) );
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first four entries of each vector
|
||||
// Lexicographic order, remaining entries of vector ignored
|
||||
function _sort_vectors4(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
let( pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y[0] < pivot[0] ||
|
||||
(y[0]==pivot[0] && (y[1]<pivot[1] ||
|
||||
(y[1]==pivot[1] && (y[2]<pivot[2] ||
|
||||
(y[2]==pivot[2] && y[3]<pivot[3])))))) y ],
|
||||
|
||||
equal = [ for (y = arr) if (y[0] == pivot[0] && y[1]== pivot[1] && y[2]==pivot[2] && y[3]==pivot[3]) y ],
|
||||
greater = [ for (y = arr) if (y[0] > pivot[0] ||
|
||||
(y[0]==pivot[0] && (y[1]>pivot[1] ||
|
||||
(y[1]==pivot[1] && (y[2]>pivot[2] ||
|
||||
(y[2]==pivot[2] && y[3]>pivot[3])))))) y ]
|
||||
len(arr)<=1 ? arr : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [
|
||||
for (y = arr) if (
|
||||
y[0] < pivot[0] || (
|
||||
y[0]==pivot[0] && (
|
||||
y[1]<pivot[1] || (
|
||||
y[1]==pivot[1] && (
|
||||
y[2]<pivot[2] || (
|
||||
y[2]==pivot[2] &&
|
||||
y[3]<pivot[3]
|
||||
)
|
||||
concat( _sort_vectors4(lesser), equal, _sort_vectors4(greater) );
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
) y
|
||||
],
|
||||
equal = [
|
||||
for (y = arr) if (
|
||||
y[0] == pivot[0] &&
|
||||
y[1] == pivot[1] &&
|
||||
y[2] == pivot[2] &&
|
||||
y[3] == pivot[3]
|
||||
) y
|
||||
],
|
||||
greater = [
|
||||
for (y = arr) if (
|
||||
y[0] > pivot[0] || (
|
||||
y[0]==pivot[0] && (
|
||||
y[1]>pivot[1] || (
|
||||
y[1]==pivot[1] && (
|
||||
y[2]>pivot[2] || (
|
||||
y[2]==pivot[2] &&
|
||||
y[3]>pivot[3]
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
) y
|
||||
]
|
||||
) concat( _sort_vectors4(lesser), equal, _sort_vectors4(greater) );
|
||||
|
||||
|
||||
function _sort_general(arr, idx=undef) =
|
||||
@ -505,9 +563,7 @@ function sort(list, idx=undef) =
|
||||
size[1]==2 ? _sort_vectors2(list) :
|
||||
size[1]==3 ? _sort_vectors3(list) :
|
||||
/*size[1]==4*/ _sort_vectors4(list)
|
||||
) :
|
||||
_sort_general(list);
|
||||
|
||||
) : _sort_general(list);
|
||||
|
||||
|
||||
// Function: sortidx()
|
||||
@ -532,18 +588,18 @@ function sort(list, idx=undef) =
|
||||
// idxs2 = sortidx(lst, idx=0); // Returns: [1,2,0,3]
|
||||
// idxs3 = sortidx(lst, idx=[1,3]); // Returns: [3,0,2,1]
|
||||
function sortidx(list, idx=undef) =
|
||||
list==[] ? [] :
|
||||
let(
|
||||
list==[] ? [] : let(
|
||||
size = array_dim(list),
|
||||
aug = is_undef(idx) && (len(size) == 1 || (len(size) == 2 && size[1]<=4)) ? zip(list, list_range(len(list))) :
|
||||
aug = is_undef(idx) && (len(size) == 1 || (len(size) == 2 && size[1]<=4))?
|
||||
zip(list, list_range(len(list))) :
|
||||
enumerate(list,idx=idx)
|
||||
)
|
||||
is_undef(idx) && len(size) == 1 ? subindex(_sort_vectors1(aug),1) :
|
||||
is_undef(idx) && len(size) == 2 && size[1] <=4 ? (
|
||||
size[1]==0 ? list_range(len(arr)) :
|
||||
size[1]==1 ? subindex(_sort_vectors1(aug),1) :
|
||||
size[1]==2 ? subindex(_sort_vectors2(aug),2) :
|
||||
size[1]==3 ? subindex(_sort_vectors3(aug),3) :
|
||||
is_undef(idx) && len(size) == 1? subindex(_sort_vectors1(aug),1) :
|
||||
is_undef(idx) && len(size) == 2 && size[1] <=4? (
|
||||
size[1]==0? list_range(len(arr)) :
|
||||
size[1]==1? subindex(_sort_vectors1(aug),1) :
|
||||
size[1]==2? subindex(_sort_vectors2(aug),2) :
|
||||
size[1]==3? subindex(_sort_vectors3(aug),3) :
|
||||
/*size[1]==4*/ subindex(_sort_vectors4(aug),4)
|
||||
) :
|
||||
// general case
|
||||
|
Loading…
x
Reference in New Issue
Block a user