# for loop ## Function `for` is used to repeatedly execute code, loop by integer range, infinite loop, and also used to traverse arrays, objects and strings. Arrays are traversed by subscript and value, objects are traversed by key and value, and strings are traversed by characters. Integer and interval loops use a lazy iteration state and do not generate the complete array in advance. ## Syntax ```bt // Infinite loop for { statement } // Repeat count times for count { statement } // Repeat count times; i is the index for i in count { statement } // Repeat count times; i starts at 0 and increases by step_value for i in count step step_value { statement } // From start to end; i is the index for i in start..end { statement } // From 0 to end; i is the index for i in ..end { statement } // Increase indefinitely from start; i is the index for i in start.. { statement } // Forward and reverse step sizes for i in start..end step step_value { statement } // Iterate over an iterable for value in iterable { value } // Iterate over an object for key, value in iterable { value } // The comma is optional for key value in iterable { value } // _ placeholder for _, value in iterable { value } // Destructuring assignment for (name, age) in iterable { name } // Labeled loop, mainly for nested for loops for:label key, value in iterable { break:label } ``` ## Parameters | Parameters | Type | Required | Description | |---|---|---|---| | count | Int | Yes | The number of loops, must be a non-negative integer. | | start | Int | No | Starting point of the interval, defaults to `0` when omitted. | | end | Int | No | The end point of the closed interval. When omitted, it means infinite increment starting from `start`. | | step_value | Int | No | Positive integer step size, default `1`; used to control the current value increment when looping, and used to control the interval step when looping. | | iterable | Array/Object/String/Int | Yes | Iterable values; integers are lazily looped `0..count - 1`. | | key | String/Int | No | Arrays and strings are subscripts, objects are key, the integer number of loops is the current integer, and the interval is a zero-based sequence number. | | value | Any | No | The current element value; the current integer in interval and integer loops. | | _ | Empty | No | Placeholder index variable | ## Return value The `for` statement itself returns `empty`. If you need to collect results, you usually create an array or object first and write it in the loop body. ## Infinite loop `for {}` represents an infinite loop, which needs to be exited through `break`, `return` or `exit` within the loop body. ```bt i = 0 for { if i >= 3 { break } println i i += 1 } ``` ## Repeat N times When no index is needed, write the count directly. ```bt for 3 { println 'hello' } ``` When indexing is required, use `for i in count`. The index starts at `0` and ends at `count - 1`. ```bt for i in 3 { println i } ``` Use `for i in count step step_value` when you need to fix the number of loops but increment the variable by a specified step size. The following will loop three times, outputting `0`, `2`, `4`. ```bt for i in 3 step 2 { println i } ``` ## Interval loop `start..end` is a closed interval, including left and right boundaries. It increases when the starting point is less than or equal to the end point, and decreases when the starting point is greater than the end point. ```bt for i in 1..3 { println i } for i in 3..1 { println i } ``` `..end` is equivalent to `0..end`. ```bt for i in ..3 { println i } ``` `start..` means infinite increment from the starting point. ```bt for i in 100.. { if i > 102 { break } println i } ``` ## step `step` controls how far the loop variable changes on each `for` iteration. A count-based loop always runs `count` times and increases its variable from `0` by `step` on each iteration. For an interval loop, the relationship between the start and end values determines the direction automatically. ### Syntax `for in step ` `for in step ` ## Constraints - `step` must be an integer greater than `0`** - Negative step sizes are not supported (the direction is automatically determined by the interval) ## Rules of conduct ### 1. Default step size When `step` is omitted, the step size defaults to `1`. ### 2. Number of cycles `for i in count step step_value` runs `count` times. The values of `i` are `0`, `step_value`, `step_value * 2`, and so on; `count` is not treated as the endpoint of a closed interval. ### 3. Automatic direction determination - **Forward iteration**: when `start ≤ end`, the loop variable increases by `step`. - **Reverse iteration**: when `start > end`, the loop variable decreases by `step`. ### 4. Interval characteristics - The interval is a **closed interval**: both the starting value and the ending value will be iterated (if the step size can be reached accurately) - Forward iteration termination condition: `variable > end` - Reverse iteration termination condition: `variable < end` ### Example | Code | Iteration Sequence | Description | |------|----------|------| | `for i in 3 step 2` | 0, 2, 4 | Loop 3 times, the current value increases by 2 | | `for i in 0..6` | 0, 1, 2, 3, 4, 5, 6 | Default step size 1, forward | | `for i in 0..6 step 2` | 0, 2, 4, 6 | Step size 2, forward | | `for i in 6..0` | 6, 5, 4, 3, 2, 1, 0 | Default step size 1, reverse | | `for i in 6..0 step 2` | 6, 4, 2, 0 | Step size 2, reverse | | `for i in 1..10 step 3` | 1, 4, 7, 10 | Step size 3, forward | | `for i in 10..1 step 3` | 10, 7, 4, 1 | Step size 3, reverse | ```bt for i in 3 step 2 { // 0, 2, 4 println i } for i in 0..6 step 2 { // 0, 2, 4, 6 println i } for i in 6..0 step 2 { // 6, 4, 2, 0 println i } ``` ### Design principles `step` only defines the change range (absolute value of the step size) of each iteration. The iteration direction of the interval loop is completely determined implicitly by the size relationship between the start and the end, which avoids the redundancy of explicitly specifying negative step sizes such as `-2`. ## Traverse the collection When you only care about the element itself, just write a variable. ```bt names = ['Lisa', 'Suci', 'Emerie'] for name in names { println name } ``` When a subscript or object key is required, write two variables: the first is the key and the second is the value. The comma between two variables can be written or omitted. ```bt users = {name: 'Lisa', age: 18} for key, value in users { println key + ': ' + string(value) } for key value in users { println key + ': ' + string(value) } ``` ## Discard binding `_` means discarding the current binding and will not create or overwrite variables named `_`. ```bt for _, value in users { println value } for key, _ in users { println key } for _, _ in users { println 'item' } ``` ## Destructure the current value When iterating over objects or arrays in an array, use parentheses after `for` to destructure the current value and select only the fields needed by the loop body. ```bt users = [ {name: ' Zhang San', age: 18} {name: ' Li Si', age: 20} ] for (name age) in users { println name + ':' + string(age) } ``` The preceding form is equivalent to: ```bt for index, user in users { name = user.name age = user.age println name + ':' + string(age) } ``` Variables inside the parentheses can be separated by spaces or commas. When the current value is an object, fields with the same names are read; when it is an array, elements are read by index. A missing field or index is assigned `empty`. A runtime error occurs when the current value is neither an array nor an object. ## break and continue `break` immediately ends the current loop; `continue` skips the remaining statements in the current iteration and starts the next one. ```bt for index, value in [1, 2, 3, 4] { if value == 2 { continue } if value == 4 { break } println value } ``` ## Label loop In nested loops, you can label the loop and then use `break:label` or `continue:label` to control the specified level. The colon is used to clearly indicate that it is followed by a jump label. The label is written after the loop keyword in the format of `for:a`, `while:a` or `loop:a`. ```bt arr = ['Lisa', 'Suci', 'Emerie'] list = ['Rita', 'maria', 'Jenna'] for:a k1, v1 in arr { for:b k2, v2 in list { if k1 == 1 { break:a } if k2 == 1 { continue:b } println v2 } println v1 } ``` ## Notes - The count in `for count {}` must be a non-negative integer; `0` performs zero iterations. - When count in `for i in count {}` is an integer, press `0..count - 1` to cycle; `for i in count step step_value {}` will cycle count times, and i will increase by step_value starting from `0`. - Interval loops only support integers, and the first version does not support floating point steps. - `start..end` contains end. - `start..` is an infinite increment interval, which usually needs to be matched with `break` in the loop body. - `for value in obj` still reads the object value; use `for key, value in obj` or `for key value in obj` when an object key is required.