forEach: Difference between revisions

From Bohemia Interactive Community
m (template:command argument fix)
m (Minor fixes)
Line 1: Line 1:
{{Command|= Comments
{{Command|Comments=
____________________________________________________________________________________________
____________________________________________________________________________________________


| ofp |= Game name
| ofp |Game name=


|1.00|= Game version
|1.00|Game version=
____________________________________________________________________________________________
____________________________________________________________________________________________


| Executes the given command(s) on every item of an array.
| Executes the given command(s) on every item of an array.<br>
<br>
The array items are represented by the [[Magic Variables|magic variable]] '''[[_x]]'''. The array indices are represented by '''[[_forEachIndex]]'''.<br>
The array items are represented by the [[Magic Variables|magic variable]] '''_x'''. The array indices are represented by '''_forEachIndex'''.
In {{arma2}} and later, the variable [[_x]] is always local to the [[forEach]] block so it is safe to nest them. |DESCRIPTION=
<br>
In ArmA2 & VBS2, the variable _x is always local to the forEach block so it is safe to nest them.
|DESCRIPTION=
____________________________________________________________________________________________
____________________________________________________________________________________________


| script '''forEach''' array |SYNTAX=
| code [[forEach]] array |SYNTAX=


|p1= script: [[String]] or [[Code]] (OFP / {{arma}}) |PARAMETER1=
|p1= code:
* [[String]] ({{ofp}}&nbsp;/&nbsp;{{arma}})
* [[Code]] ({{arma}} and later) |PARAMETER1=


|p2= array: [[Array]] |PARAMETER2=
|p2= array: [[Array]] - the array to iterate |PARAMETER2=


| [[Anything]] - will return the value of last executed statement |RETURNVALUE=
| [[Anything]] - will return the value of last executed statement |RETURNVALUE=
____________________________________________________________________________________________
____________________________________________________________________________________________
   
   
|x1= <code>{ [[Magic Variables|_x]] [[setDammage]] 1; } [[forEach]] [[units]] [[group]] [[player]];</code> |EXAMPLE1=
|x1= <code>{{cc|SQF}}
{ [[_x]] [[setDamage]] 1 } [[forEach]] [[units]] [[group]] [[player]];</code>
<code>{{codecomment|; SQS}}
"[[_x]] [[setDammage]] 1" [[forEach]] [[units]] [[group]] [[player]]</code> |EXAMPLE1=


|x2= This command can also easily be used to execute a single command multiple times without respect to the array items.
|x2= This command can also easily be used to execute a single command multiple times without respect to the array items.
<code>{ [[player]] [[addMagazine]] "M16"; } [[forEach]] [1, 2, 3, 4];</code> |EXAMPLE2=
<code>{ [[player]] [[addMagazine]] "30Rnd_556x45_Stanag"; } [[forEach]] [1, 2, 3, 4];</code> |EXAMPLE2=


|x3= You can also use multiple commands in the same block.
|x3= You can also use multiple commands in the same block:
<code>{
<code>{
     [[Magic Variables|_x]] [[setCaptive]] [[true]];
     [[Magic Variables|_x]] [[setCaptive]] [[true]];
Line 36: Line 38:
} [[forEach]] [[units]] [[group]] [[this]];</code> |EXAMPLE3=
} [[forEach]] [[units]] [[group]] [[this]];</code> |EXAMPLE3=


|x4= To get the index of a [[forEach]] loop, use [[_forEachIndex]].
|x4= To get the index of a [[forEach]] loop, use [[_forEachIndex]]:
<code>{[[systemChat]] [[format]] ["%1", _forEachIndex];} [[forEach]] [1,2,3];</code>
<code>{ [[systemChat]] [[format]] ["%1", _forEachIndex]; } [[forEach]] [1,2,3]; {{cc|will return: "0", "1", "2" in [[systemChat]] messages}}</code> |EXAMPLE4=
Will return: "0", "1", "2" in [[systemChat]] messages. |EXAMPLE4=
____________________________________________________________________________________________
____________________________________________________________________________________________


| [[set]], [[resize]], [[pushBack]], [[pushBackUnique]], [[apply]], [[reverse]], [[select]], [[in]], [[find]], [[findIf]], [[toArray]], [[toString]], [[count]], [[deleteAt]], [[deleteRange]], [[append]], [[sort]], [[param]], [[params]], [[arrayIntersect]], [[Control Structures]], [[splitString]], [[joinString]] |SEEALSO=
| [[set]], [[resize]], [[pushBack]], [[pushBackUnique]], [[apply]], [[reverse]], [[select]], [[in]], [[find]], [[findIf]], [[toArray]], [[toString]], [[count]], [[deleteAt]], [[deleteRange]], [[append]], [[sort]], [[param]], [[params]], [[arrayIntersect]], [[Control Structures]], [[splitString]], [[joinString]] |SEEALSO=
}}
}}


Line 50: Line 50:


<dd class="notedate">Posted on July 20, 2010
<dd class="notedate">Posted on July 20, 2010
<dt class="note">'''[[User:Kronzky|Kronzky]]'''
<dt class="note">[[User:Kronzky|Kronzky]]
<dd class="note">
<dd class="note">
If arrays are used in forEach loops, _x uses them by reference, so any changes to _x will be applied to the original:
If arrays are used in forEach loops, _x uses them by reference, so any changes to _x will be applied to the original:
<code>_arr1 = [1,2,3];
<code>_arr1 = [1,2,3];
_arr2 = [6,7,8];
_arr2 = [6,7,8];
{_x [[set]] [1,"x"]} [[forEach]] [_arr1,_arr2];</code>
{ [[_x]] [[set]] [1,"x"] } [[forEach]] [_arr1,_arr2];</code>
will change _arr1 to [1,"x",3], and _arr2 to [6,"x",8].
will change _arr1 to [1,"x",3], and _arr2 to [6,"x",8].
<!-- Note Section END -->
<!-- Note Section END -->
Line 61: Line 61:


<h3 style="display:none">Bottom Section</h3>
<h3 style="display:none">Bottom Section</h3>
[[Category:Scripting Commands|FOREACH]]
[[Category:Scripting Commands|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.46|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.96|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.99|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.99|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.96|FOREACH]]
[[Category:Scripting Commands ArmA|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.46|FOREACH]]
[[Category:Scripting Commands ArmA|FOREACH]]
[[Category:Command_Group:_Program_Flow|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands ArmA2|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands ArmA2|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands Arma 3|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands Arma 3|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting_Commands_Take_On_Helicopters|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting_Commands_Take_On_Helicopters|{{uc:{{PAGENAME}}}}]]
[[Category:Command_Group:_Program_Flow|{{uc:{{PAGENAME}}}}]]


<!-- CONTINUE Notes -->
<!-- CONTINUE Notes -->
Line 77: Line 77:
<dd class="note">
<dd class="note">
[[forEach]] returns any (the last passed value will be the return value or just [[Nothing]], depends on the function called).
[[forEach]] returns any (the last passed value will be the return value or just [[Nothing]], depends on the function called).
<code>
<code>_var = {_x} [[forEach]] [ [[nil]],"s",[[objNull]],[[configFile]] ]; {{cc|return bin\config.bin}}
_var = {_x} [[forEach]] [ [[nil]],"s",[[objNull]],[[configFile]] ]; // return bin\config.bin
_var = {_x [[setCaptive]] [[true]]} [[forEach]] [[allUnits]]; {{cc|return nothing}}</code>
_var = {_x [[setCaptive]] [[true]]} [[forEach]] [[allUnits]]; // return nothing
</code>
</dd>
</dd>
</dl>
<!-- DISCONTINUE Notes -->


<dl class="command_description">
<dd class="notedate">Posted on September 20, 2014</dd>
<dd class="notedate">Posted on September 20, 2014</dd>
<dt class="note">[[User:Mossarelli|Mossarelli]]</dt>
<dt class="note">[[User:Mossarelli|Mossarelli]]</dt>
Line 105: Line 100:
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".
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".
</dd>
</dd>
</dl>


<!-- CONTINUE Notes -->
<dl class="command_description">
<dd class="notedate">Posted on January 2, 2015 - 22:35 (UTC)</dd>
<dd class="notedate">Posted on January 2, 2015 - 22:35 (UTC)</dd>
<dt class="note">[[User:Heeeere's Johnny!|Heeeere's Johnny!]]</dt>
<dt class="note">[[User:Heeeere's Johnny!|Heeeere's Johnny!]]</dt>
Line 119: Line 111:
//_result = "Hello"</code>
//_result = "Hello"</code>
</dd>
</dd>
</dl>
<!-- DISCONTINUE Notes -->


<!-- CONTINUE Notes -->
<dl class="command_description">
<dd class="notedate">Posted on November 28, 2017 - 13:46 (UTC)</dd>
<dd class="notedate">Posted on November 28, 2017 - 13:46 (UTC)</dd>
<dt class="note">[[User:dedmen|dedmen]]</dt>
<dt class="note">[[User:dedmen|dedmen]]</dt>
Line 131: Line 119:


The forEach code is doing the same as
The forEach code is doing the same as
<code>
<code>_forEachIndex = 0;
_forEachIndex = 0;
while {_forEachIndex < count _array} do {
while {_forEachIndex < count _array} do {
     (_array select _forEachIndex) call code;
     (_array select _forEachIndex) call code;
     _forEachIndex = _forEachIndex + 1;
     _forEachIndex = _forEachIndex + 1;
}
}</code>
</code>


So if you delete your current element from the array the other elements will shift forward. Meaning you skip one element.<br>
So if you delete your current element from the array the other elements will shift forward. Meaning you skip one element.<br>
Line 146: Line 132:
After the first iteration your Array will be [2,3,4,5,6] and the _forEachIndex will be 1.<br>
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 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
So in the end you will only iterate over 1,3 and 6.
 
</dd>
</dd>
</dl>
</dl>
<!-- DISCONTINUE Notes -->
<!-- DISCONTINUE Notes -->

Revision as of 13:14, 25 August 2019

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 Arma 2 and later, the variable _x is always local to the forEach block so it is safe to nest them.
Groups:
Uncategorised

Syntax

Syntax:
code forEach array
Parameters:
code:
  • String (Operation Flashpoint / Arma)
  • Code (Arma and later)
array: Array - the array to iterate
Return Value:
Anything - will return the value of last executed statement

Examples

Example 1:
// SQF { _x setDamage 1 } forEach units group player; ; SQS "_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 "30Rnd_556x45_Stanag"; } 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:
setresizepushBackpushBackUniqueapplyreverseselectinfindfindIftoArraytoStringcountdeleteAtdeleteRangeappendsortparamparamsarrayIntersectControl 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.