Arma 3 Scripting

Command in Program Flow, Arrays, HashMap

forEach

Also available as Markdown and JSON, or read the original wiki page.

Description

Executes the given command(s) on every item of an Array or a HashMap.

Note

Arma 2: Since Arma 2, the variable _x is always private to the forEach block so it is safe to nest them (see #Example 8).

Syntax

Syntax 1

code forEach array

Parameters:

Returns: Anything - will return the value of last executed statement

Syntax 2

since arma3 2.02

code forEach hashMap

Parameters:

Returns: Anything - will return the value of last executed statement

Examples

Example 1

// SQF
{ _x setDamage 1 } forEach units player;
; SQS
"_x setDammage 1" forEach units player

Example 2

This command can also easily be used to execute a single command multiple times without respect to the array items - see also for

{ player addMagazine "30Rnd_556x45_Stanag" } forEach [1, 2, 3, 4];
// equivalent to
for "_i" from 1 to 4 do { player addMagazine "30Rnd_556x45_Stanag" };

Example 3

You can also use multiple commands in the same block:

{
    _x setCaptive true;
    removeAllWeapons _x;
    doStop _x;
} forEach units group this;

Example 4

To get the index of a forEach loop, use _forEachIndex:

{ systemChat str _forEachIndex; } forEach ["a", "b", "c"]; // will return: "0", "1", "2" in systemChat messages

Example 5

Iterating a HashMap's _forEachIndex:

// shows "0, k1, v1", "1, k2, v2" in systemChat messages
{
    systemChat format ["%1, %2, %3", _forEachIndex, _x, _y];
} forEach createHashMapFromArray [
    ["k1", "v1"],
    ["k2", "v2"]
];

Example 6

findIf equivalent for HashMap:

private _resultKey = {
    if (_y isEqualTo "wantedValue") exitWith { _x };
    ""
} forEach _hashmap;

Example 7

Array is edited by reference:

_arr1 = [1,2,3];
_arr2 = [6,7,8];
_arr3 = [0];
{ _x set [1, "changed"] } forEach [_arr1, _arr2, _arr3];
// _arr1 = [1, "changed", 3]
// _arr2 = [6, "changed", 8]
// _arr3 = [0, "changed"]

Example 8

{
    private _verticalValue = _x; // needed, otherwise _horizontalValues' _x made this one inaccessible
    {
        [_x, _verticalValue] call TAG_fnc_doSomething;
    } forEach _horizontalValues;
} forEach _verticalValues;

See also

Control Structures · for · apply · while · select · findIf · count · forEachReversed

Community notes

Dedmen

Be careful when deleting (deleteAt) elements from an Array while you iterate over it.

_forEachIndex will not move to reflect your change.

The forEach code is doing the same as

private _forEachIndex = 0;
while { _forEachIndex < count _array } do
{
    (_array select _forEachIndex) call code;
    _forEachIndex = _forEachIndex + 1;
};

So if you delete your current element from the array the other elements will shift forward. Meaning you skip one element.

Example:

_array = [1,2,3,4,5,6];
{ _array deleteAt _forEachIndex } forEach _array;

After the first iteration your Array will be [2,3,4,5,6] and the _forEachIndex will be 1.

So on next iteration you get the element at index 1 which will be 3. So you've just skipped the 2.

So in the end you will only iterate over 1, 3 and 6.

Sa-Matra

Use new forEachReversed command for deleting array items with deleteAt. Check its examples for details.