OpenSCAD User Manual/List Comprehensions

Basic Syntax
The list comprehensions provide a flexible way to generate lists using the general syntax

[ list-definition expression ]

The following elements are supported to construct the list definition


 * for (i = sequence) : Iteration over a range or an existing list
 * for (init;condition;next) : Simple recursive call represented as C-style for
 * each : Takes a sequence value as argument, and adds each element to the list being constructed. each x is equivalent to `for (i = x) i`
 * if (condition) : Selection criteria, when true the expression is calculated and added to the result list
 * let (x = value) : Local variable assignment

multiple generator expressions
The list comprehension syntax is generalized to allow multiple expressions. This allows to easily construct lists from multiple sub lists generated by different list comprehension expressions avoiding concat.

for
The for element defines the input values for the list generation. The syntax is the same as used by the for iterator. The sequence to the right of the equals sign can be any list. The for element iterates over all the members of the list. The variable on the left of the equals sign take on the value of each member of the sequence in turn. This value can then be processed in the child of the for element, and each result becomes a member of the final list that is produced.

If the sequence has more than one dimension, for iterates over the first dimension only. Deeper dimensions can be accessed by nesting for elements.

Several common usage patterns are presented here.


 * [ for (i = [start &#58; step &#58; end]) i ] : Generate output based on a range definition, this version is mainly useful to calculate list values or access existing lists using the range value as index.

Examples


 * [ for (i = [a, b, c, ...]) i ] : Use list parameter as input, this version can be used to map input values to calculated output values.

Examples


 * [ for (c = "String") c ] : Generate output based on a string, this iterates over each character of the string.

Examples


 * [ for (a = inita, b = initb, ...;condition;a = nexta, b = nextb, ...) expr ] : Generator for expressing simple recursive call in a c-style for loop.

The recursive equivalent of this generator is function f(a, b, ...) = condition ? concat([expr], f(nexta, nextb, ...)) : []; f(inita, initb, ...)

Examples

each
each embeds the values of a list given as argument directly, effectively unwrapping the argument list.

each unwraps ranges and helps to build more general for lists when combined with multiple generator expressions.

if
The if element allows selection if the expression should be allocated and added to the result list or not. In the simplest case this allows filtering of an list.


 * [ for (i = list) if (condition(i)) i ] : When the evaluation of the condition returns true, the expression i is added to the result list.

Example

Note that the if element cannot be inside an expression, it should be at the top.

Example

if/else
The if-else construct is equivalent to the conditional expression ?: except that it can be combined with filter if.


 * [ for (i = list) if (condition(i)) x else y ] : When the evaluation of the condition returns true, the expression x is added to the result list else the expression y.

Note that in the expression above the conditional operator could not substitute if-else. It is possible to express this same filter with the conditional operator but with a more cryptic logic:

To bind an else expression to a specific if, it's possible to use parenthesis.

let
The let element allows sequential assignment of variables inside a list comprehension definition.


 * [ for (i = list) let (assignments) a ]

Example

Nested loops
There are different ways to define nested loops. Defining multiple loop variables inside one for element and multiple for elements produce both flat result lists. To generate nested result lists an additional [ ] markup is required.

Advanced Examples
This chapter lists some advanced examples, useful idioms and use-cases for the list comprehension syntax.

Generating vertices for a polygon


Using list comprehension, a parametric equation can be calculated at a number of points to approximate many curves, such as the following example for an ellipse (using polygon):

Flattening a nested vector
List comprehension can be used in a user-defined function to perform tasks on or for vectors. Here is a user-defined function that flattens a nested vector.

Sorting a vector
Even a complicated algorithm Quicksort becomes doable with for, if, let and recursion:

Selecting elements of a vector
select performs selection and reordering of elements into a new vector.

Concatenating two vectors
Using indices:

Without using indices: