forEach: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
m (template:command argument fix)
m (Text replacement - "[[Category:Scripting Commands ArmA|" to "[[Category:Scripting Commands Armed Assault|")
(3 intermediate revisions by the same user not shown)
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 Armed Assault|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands OFP 1.46|FOREACH]]
[[Category:Scripting Commands Arma 2|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands ArmA|FOREACH]]
[[Category:Scripting Commands Arma 3|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands Take On Helicopters|{{uc:{{PAGENAME}}}}]]
[[Category:Command_Group:_Program_Flow|{{uc:{{PAGENAME}}}}]]
[[Category:Command_Group:_Program_Flow|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands ArmA2|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting Commands Arma 3|{{uc:{{PAGENAME}}}}]]
[[Category:Scripting_Commands_Take_On_Helicopters|{{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 20:10, 3 June 2020

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 or on the Forums.
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.