From 5edbb339bf088bc4f0e5de3ff36fd558988a45d0 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Tue, 11 Jun 2019 19:26:06 -0700 Subject: [PATCH] Added list_set, list_increasing, list_decreasing --- arrays.scad | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/arrays.scad b/arrays.scad index 28f4607..e694cb8 100644 --- a/arrays.scad +++ b/arrays.scad @@ -150,6 +150,44 @@ function list_range(n=undef, s=0, e=undef, step=1) = function reverse(list) = [ for (i = [len(list)-1 : -1 : 0]) list[i] ]; +// Function: list_set() +// Usage: +// list_set(indices, values, list, [dflt], [minlen]) +// Description: +// Takes the input list and returns a new list such that `list[indices[i]] = values[i]` for all of +// the (index,value) pairs supplied. If you supply `indices` that are beyond the length of the list +// then the list is extended and filled in with the `dflt` value. If you set `minlen` then the list is +// lengthed, if necessary, by padding with `dflt` to that length. The `indices` list can be in any +// order but run time will be (much) faster for long lists if it is already sorted. Reptitions are +// not allowed. +// Arguments: +// indices = List of indices into `list` to set. +// values = List of values to set. +// list = List to set items in. +// dflt = Default value to store in sparse skipped indices. +// minlen = Minimum length to expand list to. +function list_set(indices,values,list=[],dflt=0,minlen=0) = + !is_list(indices) ? list_set(list,[indices],[values],dflt) : + assert(len(indices)==len(values),"Index list and value list must have the same length") + let( + sortind = list_increasing(indices) ? list_range(len(indices)) : sortidx(indices), + lastind = indices[select(sortind,-1)] + ) + concat( + [for(j=[0:1:indices[sortind[0]]-1]) j>=len(list) ? dflt : list[j]], + [values[sortind[0]]], + [for(i=[1:1:len(sortind)-1]) each + assert(indices[sortind[i]]!=indices[sortind[i-1]],"Repeated index") + concat( + [for(j=[1+indices[sortind[i-1]]:1:indices[sortind[i]]-1]) j>=len(list) ? dflt : list[j]], + [values[sortind[i]]] + ) + ], + slice(list,1+lastind, len(list)), + replist(dflt, minlen-lastind-1) + ); + + // Function: list_remove() // Usage: // list_remove(list, elements) @@ -158,9 +196,16 @@ function reverse(list) = [ for (i = [len(list)-1 : -1 : 0]) list[i] ]; // Arguments: // list = The list to remove items from. // elements = The list of indexes of items to remove. -function list_remove(list, elements) = [ - for (i = [0:1:len(list)-1]) if (!search(i, elements)) list[i] -]; +function list_remove(list, elements) = + !is_list(elements) ? list_remove(list,[elements]) : + let( sortind = list_increasing(elements) ? list_range(len(elements)) : sortidx(elements), + lastind = elements[select(sortind,-1)] + ) + assert(lastind=len(list)-1 ? true : false); + + +// 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) : + (ind>=len(list)-1 ? true : false); + + // Function: list_shortest() // Description: // Returns the length of the shortest sublist in a list of lists.