for loop


For Loop

A for loop iterates over a range of values or elements in a collection. Jai automatically provides the it variable containing the current value, and it_index containing the current iteration number.

Basic For Loop

    
for 1..5 print("%", it);  // Outputs: 1 2 3 4 5
    

Here we iterate over a number range. The it variable holds the current value, while it_index tracks which iteration we're on.

Note that for loops copy the value inside of the collection into the iterator, so if you try and modify the data that it uses, it does not modify the underlying collection. To do this, see the section on iteration by pointer.

Named Iterator

    
for i: 1..5 {
    print("Value: %, Index: %\n", i, it_index);
}
    

You can give the iterator a custom name instead of using the default it. This improves readability, especially in nested loops.

Reverse Iteration

    
// Note: the range is still written as end..start
for < i: 5..0 {
    print("% ", i);  // Outputs: 5 4 3 2 1 0
}
    

The < operator before the iterator name reverses the direction of iteration.

Iterating Over Arrays

    
for array_of_things {
    print("%\n", it);
}
    

When iterating over arrays, values are copied into it. This means you cannot modify the original array elements this way.

Pointer Iteration

    
for *array_of_things {
    func_that_modifies(it);  // it is now a pointer to each element
}
    

If you want to iterate by pointer with a named iterator then you can do this:

    
for *thing : array_of_things {
    func_that_modifies(thing);  // it is now a pointer to each element
}
    

Itertion by pointer is important, because in contrast to the regular for loop we can modify the collection via the iterator.

Named Loops

Named loops allow you to assign an identifier to a loop, enabling you to break or continue specific outer loops from within nested loops.

    
outer: for 0..10 {
    for 0..10 {
        if some_condition break outer;  // Exits the outer loop entirely
    }
}
    

Without named loops, break and continue only affect the innermost loop. Named loops give you precise control over which loop to exit or continue.

Continue with Named Loops

    
outer: for i: 0..5 {
    for j: 0..5 {
        if j == 2 continue outer;  // skips to the next iteration of outer loop
        print("(%, %) ", i, j);
    }
}
    

Remove in For Loops

Jai provides a built-in remove statement that can be used inside for loops to safely remove the current element from the array being iterated. The compiler handles the bookkeeping for you, so you can continue iterating without skipping elements or running off the end. Note that the order of the original array may be modified after the loop (because of it calling unordered_remove).

Basic Usage

    
for *thing : array_of_things {
    if should_remove(thing) {
        remove thing;
    }
}
    

Note: the above also works when thing is not iterated by pointer.

The remove statement performs an unordered remove: it swaps the current element with the last element of the array and decrements the count. This makes it an O(1) operation, but it does not preserve the original order of elements.

Because elements get swapped in from the end, the loop also adjusts its index correctly so that the swapped-in element is visited on the next iteration rather than skipped.