Skip to main content

foreach

foreach walks an array, mapping, string, or buffer. Prefer it over an indexed for when you do not need the index.

foreach (type variable in aggregate)
statement;

The body may be a block. break and continue work as in for / while.

Arrays

string *names = ({ "ada", "bek", "cy" });

foreach (string name in names) {
write(name + "\n");
}

Declare the loop variable in the foreach header, or reuse an existing local:

string name;
foreach (name in names)
write(name + "\n");

Mappings

One variable receives values. Two variables receive key then value. The key must not be a ref.

mapping scores = ([ "ada": 10, "bek": 7 ]);

foreach (string name, int score in scores) {
write(name + " => " + score + "\n");
}

foreach (int score in scores) {
write(score + "\n");
}

Strings and buffers

A string iterates characters (codepoint-oriented; a multi-codepoint grapheme cluster can error if you treat it as a single indexed char — see ref). A buffer iterates bytes as int values 0–255.

foreach (int b in buf) {
write(sprintf("%02x ", b));
}

Mutating in place (ref / &)

ref (or &) on the loop variable writes back into arrays, buffers, and mapping values. It does not rewrite the source string variable.

int *nums = ({ 1, 2, 3 });
foreach (int ref n in nums)
n *= 2;
// nums is ({ 2, 4, 6 })

Details and restrictions: ref.

await inside foreach

An async function may await inside a foreach over a local aggregate. See async and the async concept guide.