In OpenSCAD, I'd like to create a string, pattern
, that starts with 'a', ends with 'c', and has enough 'b's in the middle that len(pattern)
is equal to units
. For example, if units
is 5, pattern
should be "abbbc".
The best solution I have so far is a list comprehension:
pattern = [if (units > 0) "a",
if (units > 2) for (i = [1:units - 2]) "b",
if (units > 1) "c"];
This will do, but ideally I'd like to make a string from this list? I tried str(pattern)
, but that gives a string representation of the list, with brackets, quotes, and commas.
Is there an alternative to the list comprehension that naturally results in a string?
My solution to this was a following recursive function:
// Joins strings with an optional separator and limit
//
// join(["A", "B", "C"]) -> "ABC"
// join(["A", "B", "C"], ",") -> "A,B,C"
// join(["A", "B", "C"], ",", 2) -> "A,B"
//
function join(parts, sep="", limit = undef) =
let(n = is_undef(limit) ? len(parts) : limit)
n == 0 ? "" :
n == 1 ? parts[n-1] :
str(join(parts, sep, n-1), sep, parts[n-1]);
Or one adapted from solution proposed by @T.P. in a comment here: Constructing a string in OpenSCAD is simpler and tail-recursive so can be optimized by compiler:
function join(v, s = "", i = 0) =
i >= len(v) ? s : join(v, str(s, v[i]), i+1);
Then there's O(log(n)) solution here: https://github.com/thehans/funcutils/blob/master/string.scad#L3