stringlistopenscad

Constructing a string in OpenSCAD


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?


Solution

  • 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