So we know how to manipulate arrays from Part 2. Now to the advanced stuff like copying arrays. You see, when you assign one array to another like this _array2 = _array1 you are not creating an independent array _array2 but creating a reference to _array1. If you then change _array2, _array1 will change accordingly. But this is not all, if you pass _array1 as parameter to a function then assign it to _array2 inside the function, changes to _array2 will still affect original _array1.

_array1 = [1,2,3]; _array2 = _array1; _array2 set [2,0]; //_array1 is now [1,2,0] a = { private ["_array2"]; _array2 = _this; _array2 set [2,10]; }; _array1 call a; //_array1 is now [1,2,10]

To avoid this you can either add or subtract empty array from original array, then assign result to your new array, or use + operator which will make copy of the original array rather than reference to it. Remember this to save yourself from pulling your hair out when debugging scripts.

_array1 = [1,2,3]; _array2 = [] + _array1; //_array2 is now [1,2,3] _array2 set [2,0]; //_array1 is still [1,2,3], _array2 is now [1,2,0] _array2 = _array1 + []; //_array2 is now [1,2,3] _array2 set [2,10]; //_array1 is still [1,2,3], _array2 is now [1,2,10] _array2 = _array1 - []; //_array2 is now [1,2,3] _array2 set [2,20]; //_array1 is still [1,2,3], _array2 is now [1,2,20] _array2 = +_array1; //_array2 is now [1,2,3] _array2 set [2,30]; //_array1 is still [1,2,3], _array2 is now [1,2,30]

To change a value in a deeply nested array just carry on selecting elements following array hierarchy, then when reached desired element just set its value as usual.

_array = [[1,2,3],[4,5,6],[7,8,[9,10]]]; ((_array select 2) select 2) set [0,10]; //_array is now [[1,2,3],[4,5,6],[7,8,[10,10]]]

To iterate through a single dimension of an array you can use forEach command. It does just that, goes though every element of the dimension consequently, similar to count command we looked at in the Part 1. Special variable _x will contain the current element of the array for this iteration and special variable _forEachIndex will contain index of the current element within the array, should you ever need to know it.

_array = ["John","Paul","George","Ringo","John","Paul","George","Ringo"]; _lastGeorgeIndex = -1; { if (_x == "George") then { _lastGeorgeIndex = _forEachIndex; }; } forEach _array; //_lastGeorgeIndex is now 6

Now to the fun stuff. Forget about using 3rd party functions like BIS_fnc_selectRandom to randomly pick 1 element from an array. Be smart, be in control of your scripts. The whole function could be done with a simple 1 line expression.

private ["_colours","_randomColour"]; _colours = ["green","yellow","purple","white"]; _randomColour = _colours select (floor (random (count _colours))); //neat huh?

There is also no text manipulation in ArmA as such, no regular expressions and string comparison is actually case insensitive (“hEllO” == “heLLO” is true, use switch/case if you need case sensitive comparison). But there is toArray command. It will convert any string into array of decimal ASCII values, basically array of numbers. Then you can perform your array operations and toString it back together when done. Here is practical application for you. You might want to sanitise player names and replace < and > with &lt; and &gt; so that they don’t interfere with structured text.

private ["_array","_temp","_sanitised"]; _array = toArray "<<<Killzone_Kid>>>"; _temp = []; { switch _x do { case 60 : { _temp = _temp + toArray "&lt;"; }; case 62 : { _temp = _temp + toArray "&gt;"; }; default { _temp = _temp + [_x]; }; }; } forEach _array; _sanitised = toString _temp; //_sanitised is now &lt;&lt;&lt;Killzone_Kid&gt;&gt;&gt;

This is it for this tutorial. Didn’t think it would be 3 part when I started it. Hope you found some of the tips useful.


Arrays, part 4