forEach: Difference between revisions

From Bohemia Interactive Community
mNo edit summary
(Rewrite confusing and errornous note)
Line 124: Line 124:
<!-- CONTINUE Notes -->
<!-- CONTINUE Notes -->
<dl class="command_description">
<dl class="command_description">
<dd class="notedate">Posted on June 17, 2016 - 21:51 (UTC)</dd>
<dd class="notedate">Posted on November 28, 2017 - 13:46 (UTC)</dd>
<dt class="note">[[User:Killzone Kid|Killzone Kid]]</dt>
<dt class="note">[[User:dedmen|dedmen]]</dt>
<dd class="note">
<dd class="note">
To be more precise, '''_forEachIndex''' represents NOT the index of the current array element, but the number of the loop iteration. If array is modified by reference while it is iterated through with [[forEach]] loop, '''_forEachIndex''' will NOT change to reflect that. For example:
Be careful when deleting ([[deleteAt]]) elements from an Array while you iterate over it.<br>
<code>_array = ["1","2","3","4","5","6","7","8","9"];
[[forEachIndex|_forEachIndex]] will not move to reflect your change.<br>
{
[[systemChat]] str [_x, _forEachIndex, _array];
_array [[deleteAt]] _forEachIndex;
}
[[forEach]] _array;


/*result:
The forEach code is doing the same as
[_x, _forEachIndex, _array]
<code>
["1",0,["1","2","3","4","5","6","7","8","9"]]
_forEachIndex = 0;
["3",1,["2","3","4","5","6","7","8","9"]]
while {_forEachIndex < count _array} do {
["5",2,["2","4","5","6","7","8","9"]]
    (_array select _forEachIndex) call code;
["7",3,["2","4","6","7","8","9"]]
    _forEachIndex = _forEachIndex + 1;
["9",4,["2","4","6","8","9"]]*/
}
</code>
</code>
So if you delete your current element from the array the other elements will shift forward. Meaning you skip one element.<br>
Example:
<code>_array = [1,2,3,4,5,6];
{_array deleteAt _forEachIndex} forEach _array;
</code>
After the first iteration your Array will be [2,3,4,5,6] and the _forEachIndex will be 1.<br>
So on next iteration you get the element at index 1 which will be 3. So you've just skipped the 2.<br>
So in the end you will only iterate over 1,3 and 6
</dd>
</dd>
</dl>
</dl>
<!-- DISCONTINUE Notes -->
<!-- DISCONTINUE Notes -->

Revision as of 14:46, 28 November 2017

Hover & click on the images for description

Description

Description:
Executes the given command(s) on every item of an array.
The array items are represented by the magic variable _x. The array indices are represented by _forEachIndex.
In ArmA2 & VBS2, the variable _x is always local to the forEach block so it is safe to nest them.
Groups:
Uncategorised

Syntax

Syntax:
script forEach array
Parameters:
script: String or Code (OFP / Arma)
array: Array
Return Value:
Anything - will return the value of last executed statement

Examples

Example 1:
{ _x setDammage 1; } forEach units group player;
Example 2:
This command can also easily be used to execute a single command multiple times without respect to the array items. { player addMagazine "M16"; } forEach [1, 2, 3, 4];
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 format ["%1", _forEachIndex];} forEach [1,2,3]; Will return: "0", "1", "2" in systemChat messages.

Additional Information

See also:
setresizepushBackpushBackUniqueapplyreverseselectinfindtoArraytoStringcountdeleteAtdeleteRangeappendsortparamparamsarrayIntersectControl StructuressplitStringjoinString

Notes

Report bugs on the Feedback Tracker and/or discuss them on the Arma Discord.
Only post proven facts here! Add Note

Notes

Posted on July 20, 2010
Kronzky
If arrays are used in forEach loops, _x uses them by reference, so any changes to _x will be applied to the original: _arr1 = [1,2,3]; _arr2 = [6,7,8]; {_x set [1,"x"]} forEach [_arr1,_arr2]; will change _arr1 to [1,"x",3], and _arr2 to [6,"x",8].

Bottom Section

Posted on August 29, 2014 - 22:23 (UTC)
Fett Li
forEach returns any (the last passed value will be the return value or just Nothing, depends on the function called). _var = {_x} forEach [ nil,"s",objNull,configFile ]; // return bin\config.bin _var = {_x setCaptive true} forEach allUnits; // return nothing
Posted on September 20, 2014
Mossarelli
Using the foreach loop, since there are no variable for the index like say the for-do loop, there is a variable that you can use to check the index of the foreach loop. { if (_forEachIndex == 1) then { // Copilot _x addUniform "U_B_Soldier_VR"; } else { // Adams [_x, "B_Soldier_TL_F"] call BIS_fnc_loadInventory; _x addUniform "U_B_Soldier_VR"; _x setIdentity "Bootcamp_B_Adams"; }; } forEach _crew; So when the array is past from _crew to the loop, index 1 (which is the second element) is the copilot of the "B_Heli_Light_01_F" and he will get "U_B_Soldier_VR" as a uniform. While the pilot which is index 0 (first element), will get the same uniform but will get the loadout of "B_Soldier_TL_F" and the identity of "Bootcamp_B_Adams".
Posted on January 2, 2015 - 22:35 (UTC)
Heeeere's Johnny!
Using exitWith inside a forEach loop will make forEach actually return something, namely whatever the exitWith returns: _result = { if(_x isEqualTo 3) exitWith {"Hello"} } forEach [1,2,3,4,5]; //_result = "Hello"
Posted on November 28, 2017 - 13:46 (UTC)
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 _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