Arma 3 Scripting

forEach

  • Arma 3 v0.50
  • First in Operation Flashpoint v1.00

Command · also in Arrays, HashMap · Markdown · JSON · 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.