mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 00:09:41 +00:00
list_remove fix
rename array_dim to list_shape
This commit is contained in:
parent
817165a833
commit
024011ea5e
4 changed files with 103 additions and 80 deletions
|
@ -650,7 +650,7 @@ function sort(list, idx=undef) =
|
|||
is_string(list)? str_join(sort([for (x = list) x],idx)) :
|
||||
!is_list(list) || len(list)<=1 ? list :
|
||||
is_homogeneous(list,1)
|
||||
? let(size = array_dim(list[0]))
|
||||
? let(size = list_shape(list[0]))
|
||||
size==0 ? _sort_scalars(list)
|
||||
: len(size)!=1 ? _sort_general(list,idx)
|
||||
: is_undef(idx) ? _sort_vectors(list)
|
||||
|
@ -692,7 +692,7 @@ function sortidx(list, idx=undef) =
|
|||
!is_list(list) || len(list)<=1 ? list :
|
||||
is_homogeneous(list,1)
|
||||
? let(
|
||||
size = array_dim(list[0]),
|
||||
size = list_shape(list[0]),
|
||||
aug = ! (size==0 || len(size)==1) ? 0 // for general sorting
|
||||
: [for(i=[0:len(list)-1]) concat(i,list[i])], // for scalar or vector sorting
|
||||
lidx = size==0? [1] : // scalar sorting
|
||||
|
|
148
lists.scad
148
lists.scad
|
@ -84,6 +84,59 @@ function max_length(array) =
|
|||
|
||||
|
||||
|
||||
|
||||
// Internal. Not exposed.
|
||||
function _list_shape_recurse(v) =
|
||||
!is_list(v[0])
|
||||
? len( [for(entry=v) if(!is_list(entry)) 0] ) == 0 ? [] : [undef]
|
||||
: let(
|
||||
firstlen = is_list(v[0]) ? len(v[0]): undef,
|
||||
first = len( [for(entry = v) if(! is_list(entry) || (len(entry) != firstlen)) 0 ] ) == 0 ? firstlen : undef,
|
||||
leveldown = flatten(v)
|
||||
)
|
||||
is_list(leveldown[0])
|
||||
? concat([first],_list_shape_recurse(leveldown))
|
||||
: [first];
|
||||
|
||||
function _list_shape_recurse(v) =
|
||||
let( alen = [for(vi=v) is_list(vi) ? len(vi): -1] )
|
||||
v==[] || max(alen)==-1 ? [] :
|
||||
let( add = max(alen)!=min(alen) ? undef : alen[0] )
|
||||
concat( add, _list_shape_recurse(flatten(v)));
|
||||
|
||||
|
||||
// Function: list_shape()
|
||||
// Usage:
|
||||
// dims = list_shape(v, [depth]);
|
||||
// Topics: Matrices, Array Handling
|
||||
// Description:
|
||||
// Returns the size of a multi-dimensional array, a list of the lengths at each depth.
|
||||
// If the returned value has `dims[i] = j` then it means the ith index ranges of j items.
|
||||
// The return `dims[0]` is equal to the length of v. Then `dims[1]` is equal to the
|
||||
// length of the lists in v, and in general, `dims[i]` is equal to the length of the items
|
||||
// nested to depth i in the list v. If the length of items at that depth is inconsistent, then
|
||||
// `undef` is returned. If no items exist at that depth then `0` is returned. Note that
|
||||
// for simple vectors or matrices it is faster to compute `len(v)` and `len(v[0])`.
|
||||
// Arguments:
|
||||
// v = list to get shape of
|
||||
// depth = depth to compute the size of. If not given, returns a list of sizes at all depths.
|
||||
// Example:
|
||||
// a = list_shape([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]); // Returns [2,2,3]
|
||||
// b = list_shape([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0); // Returns 2
|
||||
// c = list_shape([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2); // Returns 3
|
||||
// d = list_shape([[[1,2,3],[4,5,6]],[[7,8,9]]]); // Returns [2,undef,3]
|
||||
function list_shape(v, depth=undef) =
|
||||
assert( is_undef(depth) || ( is_finite(depth) && depth>=0 ), "Invalid depth.")
|
||||
! is_list(v) ? 0 :
|
||||
(depth == undef)
|
||||
? concat([len(v)], _list_shape_recurse(v))
|
||||
: (depth == 0)
|
||||
? len(v)
|
||||
: let( dimlist = _list_shape_recurse(v))
|
||||
(depth > len(dimlist))? 0 : dimlist[depth-1] ;
|
||||
|
||||
|
||||
|
||||
// Function: in_list()
|
||||
// Usage:
|
||||
// bool = in_list(val, list, [idx]);
|
||||
|
@ -641,31 +694,44 @@ function list_insert(list, indices, values) =
|
|||
|
||||
// Function: list_remove()
|
||||
// Usage:
|
||||
// list = list_remove(list, indices);
|
||||
// list = list_remove(list, ind);
|
||||
// Topics: List Handling
|
||||
// See Also: list_set(), list_insert(), list_remove_values()
|
||||
// Description:
|
||||
// Remove all items from `list` whose indexes are in `indices`.
|
||||
// If `ind` is a number remove `list[ind]` from the list. If `ind` is a list of indices
|
||||
// remove from the list the item all items whose indices appear in `ind`. If you give
|
||||
// indices that are not in the list they are ignored.
|
||||
// Arguments:
|
||||
// list = The list to remove items from.
|
||||
// indices = The list of indexes of items to remove.
|
||||
// ind = index or list of indices of items to remove.
|
||||
// Example:
|
||||
// a = list_insert([3,6,9,12],1); // Returns: [3,9,12]
|
||||
// b = list_insert([3,6,9,12],[1,3]); // Returns: [3,9]
|
||||
function list_remove(list, indices) =
|
||||
assert(is_list(list))
|
||||
is_finite(indices) ?
|
||||
[
|
||||
for (i=[0:1:min(indices, len(list)-1)-1]) list[i],
|
||||
for (i=[min(indices, len(list)-1)+1:1:len(list)-1]) list[i]
|
||||
]
|
||||
: indices==[] ? list
|
||||
: assert( is_vector(indices), "Invalid list `indices`." )
|
||||
// a = list_remove([3,6,9,12],1); // Returns: [3,9,12]
|
||||
// b = list_remove([3,6,9,12],[1,3]); // Returns: [3,9]
|
||||
// c = list_remove([3,6],3); // Returns: [3,6]
|
||||
function list_remove(list, ind) =
|
||||
assert(is_list(list), "Invalid list in list_remove")
|
||||
is_finite(ind) ?
|
||||
(
|
||||
(ind<0 || ind>=len(list)) ? list
|
||||
:
|
||||
[
|
||||
for (i=[0:1:ind-1]) list[i],
|
||||
for (i=[ind+1:1:len(list)-1]) list[i]
|
||||
]
|
||||
)
|
||||
: ind==[] ? list
|
||||
: assert( is_vector(ind), "Invalid index list in list_remove")
|
||||
let(sres = search(count(list),ind,1))
|
||||
[
|
||||
for(i=[0:len(list)-1])
|
||||
if ( []==search(i,indices,1) )
|
||||
list[i]
|
||||
];
|
||||
if (sres[i] == [])
|
||||
list[i]
|
||||
];
|
||||
|
||||
// This method is faster for long lists with few values to remove
|
||||
// let( rem = list_set([], indices, repeat(1,len(indices)), minlen=len(list)))
|
||||
// [for(i=idx(list)) if (rem[i]==0) list[i]];
|
||||
|
||||
|
||||
|
||||
// Function: list_remove_values()
|
||||
|
@ -931,54 +997,6 @@ function permutations(l,n=2) =
|
|||
// Section: Changing list structure
|
||||
|
||||
|
||||
// Internal. Not exposed.
|
||||
function _array_dim_recurse(v) =
|
||||
!is_list(v[0])
|
||||
? len( [for(entry=v) if(!is_list(entry)) 0] ) == 0 ? [] : [undef]
|
||||
: let(
|
||||
firstlen = is_list(v[0]) ? len(v[0]): undef,
|
||||
first = len( [for(entry = v) if(! is_list(entry) || (len(entry) != firstlen)) 0 ] ) == 0 ? firstlen : undef,
|
||||
leveldown = flatten(v)
|
||||
)
|
||||
is_list(leveldown[0])
|
||||
? concat([first],_array_dim_recurse(leveldown))
|
||||
: [first];
|
||||
|
||||
function _array_dim_recurse(v) =
|
||||
let( alen = [for(vi=v) is_list(vi) ? len(vi): -1] )
|
||||
v==[] || max(alen)==-1 ? [] :
|
||||
let( add = max(alen)!=min(alen) ? undef : alen[0] )
|
||||
concat( add, _array_dim_recurse(flatten(v)));
|
||||
|
||||
|
||||
// Function: array_dim()
|
||||
// Usage:
|
||||
// dims = array_dim(v, [depth]);
|
||||
// Topics: Matrices, Array Handling
|
||||
// Description:
|
||||
// Returns the size of a multi-dimensional array. Returns a list of dimension lengths. The length
|
||||
// of `v` is the dimension `0`. The length of the items in `v` is dimension `1`. The length of the
|
||||
// items in the items in `v` is dimension `2`, etc. For each dimension, if the length of items at
|
||||
// that depth is inconsistent, `undef` will be returned. If no items of that dimension depth exist,
|
||||
// `0` is returned. Otherwise, the consistent length of items in that dimensional depth is
|
||||
// returned.
|
||||
// Arguments:
|
||||
// v = Array to get dimensions of.
|
||||
// depth = Dimension to get size of. If not given, returns a list of dimension lengths.
|
||||
// Example:
|
||||
// a = array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]); // Returns [2,2,3]
|
||||
// b = array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0); // Returns 2
|
||||
// c = array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2); // Returns 3
|
||||
// d = array_dim([[[1,2,3],[4,5,6]],[[7,8,9]]]); // Returns [2,undef,3]
|
||||
function array_dim(v, depth=undef) =
|
||||
assert( is_undef(depth) || ( is_finite(depth) && depth>=0 ), "Invalid depth.")
|
||||
! is_list(v) ? 0 :
|
||||
(depth == undef)
|
||||
? concat([len(v)], _array_dim_recurse(v))
|
||||
: (depth == 0)
|
||||
? len(v)
|
||||
: let( dimlist = _array_dim_recurse(v))
|
||||
(depth > len(dimlist))? 0 : dimlist[depth-1] ;
|
||||
|
||||
|
||||
// Function: list_to_matrix()
|
||||
|
|
|
@ -436,7 +436,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
|
|||
assert(capsOK, "caps must be boolean or a list of two booleans")
|
||||
assert(!closed || !caps, "Cannot make closed shape with caps")
|
||||
let(
|
||||
profile_dim=array_dim(profiles,2),
|
||||
profile_dim=list_shape(profiles,2),
|
||||
profiles_zcheck = (profile_dim != 2) || (profile_dim==2 && is_list(z) && len(z)==len(profiles)),
|
||||
profiles_ok = (profile_dim==2 && is_list(z) && len(z)==len(profiles)) || profile_dim==3
|
||||
)
|
||||
|
|
|
@ -156,9 +156,14 @@ test_list_set();
|
|||
|
||||
module test_list_remove() {
|
||||
assert(list_remove([3,6,9,12],1) == [3,9,12]);
|
||||
assert(list_remove([3,6,9,12],[1]) == [3,9,12]);
|
||||
assert(list_remove([3,6,9,12],[1,3]) == [3,9]);
|
||||
assert(list_remove([3,6,9],[]) == [3,6,9]);
|
||||
assert(list_remove([],[]) == []);
|
||||
assert(list_remove([1,2,3], -1)==[1,2,3]);
|
||||
assert(list_remove([1,2,3], 3)==[1,2,3]);
|
||||
assert(list_remove([1,2,3], [-1,3])==[1,2,3]);
|
||||
assert(list_remove([1,2,3], [-1,1,3])==[1,3]);
|
||||
}
|
||||
test_list_remove();
|
||||
|
||||
|
@ -402,19 +407,19 @@ module test_full_flatten() {
|
|||
test_full_flatten();
|
||||
|
||||
|
||||
module test_array_dim() {
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) == [2,2,3]);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0) == 2);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2) == 3);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9]]]) == [2,undef,3]);
|
||||
assert(array_dim([1,2,3,4,5,6,7,8,9]) == [9]);
|
||||
assert(array_dim([[1],[2],[3],[4],[5],[6],[7],[8],[9]]) == [9,1]);
|
||||
assert(array_dim([]) == [0]);
|
||||
assert(array_dim([[]]) == [1,0]);
|
||||
assert(array_dim([[],[]]) == [2,0]);
|
||||
assert(array_dim([[],[1]]) == [2,undef]);
|
||||
module test_list_shape() {
|
||||
assert(list_shape([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) == [2,2,3]);
|
||||
assert(list_shape([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0) == 2);
|
||||
assert(list_shape([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2) == 3);
|
||||
assert(list_shape([[[1,2,3],[4,5,6]],[[7,8,9]]]) == [2,undef,3]);
|
||||
assert(list_shape([1,2,3,4,5,6,7,8,9]) == [9]);
|
||||
assert(list_shape([[1],[2],[3],[4],[5],[6],[7],[8],[9]]) == [9,1]);
|
||||
assert(list_shape([]) == [0]);
|
||||
assert(list_shape([[]]) == [1,0]);
|
||||
assert(list_shape([[],[]]) == [2,0]);
|
||||
assert(list_shape([[],[1]]) == [2,undef]);
|
||||
}
|
||||
test_array_dim();
|
||||
test_list_shape();
|
||||
|
||||
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
|
Loading…
Reference in a new issue