For-loop

Repeats a series of functions once for each key-value pair in an object.

For Value1 , Value2 in Expression

Parameters

Value1
Value2

Type: Variable

The variables in which to store the values returned by the enumerator at the beginning of each iteration. The nature of these values is defined by the enumerator, which is determined by Expression.

When the loop breaks or completes, these variables are restored to their former values.

Expression

Type: Object

An expression which results in an enumerable object, or a variable which contains an enumerable object.

Remarks

The parameter list can optionally be enclosed in parentheses. For example: for (val in myarray)

The process of enumeration is as follows:

Although not exactly equivalent to a for-loop, the following demonstrates this process:

_enum := Expression
try _enum := _enum.__Enum(2)
while %_enum%(Value1, Value2)
{
    ...
}

As in the code above, an exception is thrown if Expression or __Enum does not yield a object, or if the enumerator object cannot be called.

While enumerating properties, methods or array elements, it is generally unsafe to insert or remove items of that type. Doing so may cause some items to be skipped or enumerated multiple times. One workaround is to build a list of items to remove, then use a second loop to remove the items after the first loop completes.

A for-loop is usually followed by a block, which is a collection of statements that form the body of the loop. However, a loop with only a single statement does not require a block (an "if" and its "else" count as a single statement for this purpose). The One True Brace (OTB) style may optionally be used, which allows the open-brace to appear on the same line rather than underneath. For example: for x, y in z {.

As with all loops, Break, Continue and A_Index may be used.

COM Objects

Since Value1 and Value2 are passed directly to the enumerator, the values they are assigned depends on what type of object is being enumerated. For COM objects, Value1 contains the value returned by IEnumVARIANT::Next() and Value2 contains a number which represents its variant type. For example, when used with a Scripting.Dictionary object, each Value1 contains a key from the dictionary and Value2 is typically 8 for strings and 3 for integers. See ComObjType for a list of type codes.

When enumerating a SafeArray, Value1 contains the current element and Value2 contains its variant type.

Related

Enumerator object, OwnProps, OwnMethods, While-loop, Loop, Until, Break, Continue, Blocks

Examples

#1: List the properties owned by an object:

colours := {red: 0xFF0000, blue: 0x0000FF, green: 0x00FF00}
; The above expression could be used directly in place of "colours" below:
for k, v in colours.OwnProps()
    s .= k "=" v "`n"
MsgBox s

#2: List all open Explorer and Internet Explorer windows:

for window in ComObjCreate("Shell.Application").Windows
    windows .= window.LocationName " :: " window.LocationURL "`n"
MsgBox windows

#3: Define an enumerator as a fat arrow function. Returns numbers from the Fibonacci sequence, indefinitely or until stopped.

for n in FibF()
    if MsgBox("#" A_Index " = " n "`nContinue?",, "y/n") = "No"
        break

FibF() {
    a := 0, b := 1
    return (ByRef n) => (
        n := c := b, b += a, a := c,
        true
    )
}

#4: Define an enumerator as a class. Equivalent to the previous example.

for n in FibC.new()
    if MsgBox("#" A_Index " = " n "`nContinue?",, "y/n") = "No"
        break

class FibC {
    a := 0, b := 1
    Call(ByRef n) {
        n := c := this.b, this.b += this.a, this.a := c
        return true
    }
}