For Loop
Iterating through a numeric range or an array, or any iterable type,
is provided by the for
… in
loop.
There are two alternative syntaxes, one including a counter variable:
for
variablein
expression{
…}
for (
variable,
counter)
in
expression{
…}
Break or Continue
continue
can be used to skip to the next iteration, by-passing all following statements;
break
can be used to break out of the loop unconditionally.
For Expression
for
statements can also be used as expressions.
The break
statement takes an optional expression that provides the return value.
The default return value of a for
expression is ()
.
let a = [42, 123, 999, 0, true, "hello", "world!", 987.6543];
// 'for' can be used just like an expression
let index = for (item, count) in a {
// if the 'for' loop breaks here, return a specific value
switch item.type_of() {
"i64" if item.is_even => break count,
"f64" if item.to_int().is_even => break count,
}
// ... if the 'for' loop exits here, the return value is ()
};
if index == () {
print("Magic number not found!");
} else {
print(`Magic number found at index ${index}!`);
}
Counter Variable
The counter variable, if specified, starts from zero, incrementing upwards.
let a = [42, 123, 999, 0, true, "hello", "world!", 987.6543];
// Loop through the array
for (item, count) in a {
if x.type_of() == "string" {
continue; // skip to the next iteration
}
// 'item' contains a copy of each element during each iteration
// 'count' increments (starting from zero) for each iteration
print(`Item #${count + 1} = ${item}`);
if x == 42 { break; } // break out of for loop
}
Iterate Through Arrays
Iterating through an array yields cloned copies of each element.
let a = [1, 3, 5, 7, 9, 42];
// Loop through the array
for x in a {
if x > 10 { continue; } // skip to the next iteration
print(x);
if x == 42 { break; } // break out of for loop
}
Iterate Through Strings
Iterating through a string yields individual characters.
The chars
method also allow iterating through characters in a string,
optionally accepting the character position to start from (counting from the end if negative), as
well as the number of characters to iterate (defaults to all).
char
also accepts a range which can be created via the ..
(exclusive) and ..=
(inclusive) operators.
let s = "hello, world!";
// Iterate through all the characters.
for ch in s {
print(ch);
}
// Iterate starting from the 3rd character and stopping at the 7th.
for ch in s.chars(2, 5) {
if ch > 'z' { continue; } // skip to the next iteration
print(ch);
if x == '@' { break; } // break out of for loop
}
// Iterate starting from the 3rd character and stopping at the end.
for ch in s.chars(2..s.len) {
if ch > 'z' { continue; } // skip to the next iteration
print(ch);
if x == '@' { break; } // break out of for loop
}
Iterate Through Numeric Ranges
Ranges are created via the ..
(exclusive) and ..=
(inclusive) operators.
The range
function similarly creates exclusive ranges, plus allowing optional step values.
// Iterate starting from 0 and stopping at 49
// The step is assumed to be 1 when omitted for integers
for x in 0..50 {
if x > 10 { continue; } // skip to the next iteration
print(x);
if x == 42 { break; } // break out of for loop
}
// The 'range' function is just the same
for x in range(0, 50) {
if x > 10 { continue; } // skip to the next iteration
print(x);
if x == 42 { break; } // break out of for loop
}
// The 'range' function also takes a step
for x in range(0, 50, 3) { // step by 3
if x > 10 { continue; } // skip to the next iteration
print(x);
if x == 42 { break; } // break out of for loop
}
// The 'range' function can also step backwards
for x in range(50..0, -3) { // step down by -3
if x < 10 { continue; } // skip to the next iteration
print(x);
if x == 42 { break; } // break out of for loop
}
// It works also for floating-point numbers
for x in range(5.0, 0.0, -2.0) { // step down by -2.0
if x < 10 { continue; } // skip to the next iteration
print(x);
if x == 4.2 { break; } // break out of for loop
}
Iterate Through Bit-Fields
The bits
function allows iterating through an integer as a bit-field.
bits
optionally accepts the bit number to start from (counting from the most-significant-bit if
negative), as well as the number of bits to iterate (defaults all).
bits
also accepts a range which can be created via the ..
(exclusive) and ..=
(inclusive) operators.
let x = 0b_1001110010_1101100010_1100010100;
let num_on = 0;
// Iterate through all the bits
for bit in x.bits() {
if bit { num_on += 1; }
}
print(`There are ${num_on} bits turned on!`);
const START = 3;
// Iterate through all the bits from 3 through 12
for (bit, index) in x.bits(START, 10) {
print(`Bit #${index} is ${if bit { "ON" } else { "OFF" }}!`);
if index >= 7 { break; } // break out of for loop
}
// Iterate through all the bits from 3 through 12
for (bit, index) in x.bits(3..=12) {
print(`Bit #${index} is ${if bit { "ON" } else { "OFF" }}!`);
if index >= 7 { break; } // break out of for loop
}
Iterate Through Object Maps
Two methods, keys
and values
, return arrays containing cloned copies
of all property names and values of an object map, respectively.
These arrays can be iterated.
let map = #{a:1, b:3, c:5, d:7, e:9};
// Property names are returned in unsorted, random order
for x in map.keys() {
if x > 10 { continue; } // skip to the next iteration
print(x);
if x == 42 { break; } // break out of for loop
}
// Property values are returned in unsorted, random order
for val in map.values() {
print(val);
}