Wiki
Version 3 (modified by hopscc, 12 years ago)

--

For Expression

The for expression enables looping in expressions and results in a list with the results.

for <var> in <ienumerable> [where <condition>] get <expr>
for <var> in <ienumerable> where <condition>
for <var> in <start-expr> : stop-expr [: <step-expr> [where <condition>] get <expr> 

The var may be declared in the expression or it can be a preexisting variable. The ienumerable is any expression that implements the IEnumerable interface (Collections, arrays, streams,...).
The condition is optional and is used to filter the list.
Finally, the expr is evaluated for each individual item resulting in the elements of the final list.

The get <expr> part can be excluded in the presence of where in which case it is assumed to be get <var>.
i.e return the item from the ienumerable.

Both ienumerable and the resulting list may be empty.

The resulting list is always newly created. The type of the list is List<of T> where T is the type of expr. There is no requirement that the type of expr be the same as the type of what the ienumerable contains.

The last variant specifying start and stop steps is to generate a list containing a range of numbers similarly to a numeric for loop. All the expressions here must evaluate to an IEnumerable range (integers usually). Unlike a for-loop the start-expr must be given. The stop-expr is the value at which generation stops, this value is not returned to the list (so its a one-past the end/sentinel ). The step-expr is the step between items the sequence progresses in - if not given it defaults to 1.

If the for expression is part of a more complex expression—especially if it is the beginning of one—then put parenthesis around it to prevent the get <expr> portion of the grammar from consuming the rest of the complex expression. See below for an example.

There is also a statement version of the for loop. (EnumerableForStatement and NumericFor)

# Example 1 
t = for x in [1, 2, 3] get x*x 
# type of `x` is int, type of `t` is List<of int>
assert t.count==3 
assert t[0]==1 
assert t[1]==4 
assert t[2]==9 

# Example 2: Explicit variable typing 
names = for name as String in provider.names get name.toLower 

# Example 3: Grouping with parens 
assert (for s in ['aa', 'bbbb', 'cccccc'] get s.length) == [2, 4, 6] 
# not needed in this case: 
assert [2, 4, 6] == for s in ['aa', 'bbbb', 'cccccc'] get s.length 

# Example 3: with `where` 
names = for name in names where name.trim.length get name.trim 

# Example 4: `get x` is implied 
t = for x in numbers where x > 0 

#Example 5: numeric ranged list 
range = for i in 0 : 10 get i*i
assert range.count == 10
assert range[0] ==0
assert range[9] == 81

Python calls this construct a 'List comprehension'.