ArmA 2 Array Tutorial

ArmA 2 Forum, ArmA 2 Home, ArmA 2 Config, ArmA 2 File Formats, ArmA 2 Missions, ArmA 2 3D Modeling, ArmA 2 Scripting, ArmA 2 Terrain, ArmA 2 Texturing, ArmA 2 Tools

What are arrays?

Simplified, you may see them as list. A container that holds multiple parameters. You ca identify a array by it's surrounding square brackets [ ]. You surely already encountered arrays:

[1,2,3,4] execVM "anyScript.sqf";

I see you remember. There is a array right in front of the execVM command. In this case, the array passes parameters to “anyScript.sqf” for further use. We will look on this particular array a bit later. Let's start inside scripts first.

Creating a array.

Inside a script, a array is build exactly the same way as a variable is defined.

_myArray = [you, me, him];

Now we have a array, named “_myArray” and we filled it with 3 people.

Selecting a specific parameter out of the array

First, we have to know that index numbering is zero-based. So the very first parameter has index 0 and not 1. To select a specific parameter which position inside the array is known, we use the command select. Example based on the above created array:

_myself = _myArray select 2;

Probably you already used the “getPos” command to get a unit's position. This command also returns a array, containing 3 parameters: [lattitude, longitude, altitude] So if we want to know the altitude above ground of any object, we use the select command:

_myself = _myArray select 2;
_position = getPos _myself select 2;

“getpos _myself” returns a array from which we select the third parameter, the altitude.

The “foreach” command

Probably the most useful command when it comes to arrays. Let us rearm _myself, first without arrays;

_myself addMagazine "30Rnd_556x45_Stanag";
_myself addMagazine "30Rnd_556x45_Stanag";
_myself addMagazine "30Rnd_556x45_Stanag";
_myself addMagazine "30Rnd_556x45_Stanag";
_myself addMagazine "1Rnd_HE_M203";
_myself addMagazine "1Rnd_HE_M203";
_myself addMagazine "1Rnd_HE_M203";
_myself addMagazine "1Rnd_HE_M203";
_myself addMagazine "15Rnd_9x19_M9";
_myself addMagazine "15Rnd_9x19_M9";
_myself addMagazine "M136";
_myself addWeapon "M4A1_RCO_GL";
_myself addWeapon "M9";
_myself addWeapon "M136";

It works, but “advanced scripting” looks a bit different.

{_myself addMagazine "30Rnd_556x45_Stanag"} forEach [1,2,3,4,5,6];
{_myself addMagazine "1Rnd_HE_M203"} forEach [1,2,3,4];
{_myself addMagazine "15Rnd_9x19_M9"} forEach [1,2,3,4];
_myself addMagazine "M136";

Please take note of the variable “_x”. It is part of the foreach command. The foreach command takes each parameter of the array separately, puts it on the place of _x and then executes the command(s).

Removing elements from an array

Well, i don't feel comfortable being in one array with _myself. So, let's take “me” out of it. And you don't belong there aswell:

_myArray = [you, me, him];
_myArray = _myArray - [you, me];

After that, the array _myArray only holds him. You and me were removed from it.

Adding elements to an array

You can also add elements to arrays.

_myArray = _myArray + [newElement1,newElement2,newElement3];

These new elements will be appended to the end of the array. So if _myArray began with 2 elements, newElement1 would be at index 2.

The count command

Maybe just as (if not more) useful than forEach. Count actually has 2 syntax's. The more common one is simply:

_arrayLength = count _myArray;

It will give you the number of elements in _myArray.

The second syntax however is very powerful. It works a lot like forEach, only instead of just executing code, you can test a condition against all elements in the array and it will return the number of elements for which the condition was true.

Ex:

_myArray =
[
	"30Rnd_556x45_Stanag",
	"30Rnd_556x45_Stanag",
	"30Rnd_556x45_Stanag",
	"30Rnd_556x45_Stanag",
	"1Rnd_HE_M203",
	"1Rnd_HE_M203",
	"1Rnd_HE_M203",
	"1Rnd_HE_M203",
	"15Rnd_9x19_M9",
	"15Rnd_9x19_M9",
	"M136"
];
_numStanagMags =
{
	_X == "30Rnd_556x45_Stanag"
} count _myArray;

Returns 4.

Setting elements

If you want to change the value of an array element without adding/removing (and thus reordering) it, you can use the set command. Set takes an array, an index, and a value as arguments. It takes the array, and replaces the value of the element at the given index with the new given value.

_myArray = [you, me, him];
_myArray set [2, guy]; // replaces him with guy

I should also mention that you can use an index outside of the array's current size, and the array will be resized up to the given index (with some default/null value in all the other new indices).

Nested/2D/XD arrays

Arrays can contain any variable type, including other arrays. You can use this to create multidimensional arrays. For example, if you want to represent a 2D map with a coordinate system:

_myMap =
[
[ 0 , 0 , 0 , 0 , A , 0 , 0 , B ],
[ 0 , 0 , C , 0 , 0 , D , 0 , 0 ],
[ 0 , 0 , 0 , 0 , 0 , 0 , E , 0 ]
];
_valueD = (_myMap select 1) select 5;

The index of the primary array would be your Y coordinate, and the index in the subarray at index Y is your X coordinate.

You can also use nested arrays to pass arrays to scripts along with individual arguments.

_handle = [1, 5, [0, 1, 2], "Hello", [player, "goodbye"]] execVM "myScript.sqf";

Inside of myScript.sqf:

_this select 2; // contains the array [0, 1, 2];
_this select 4; // contains the array [player, "goodbye"];

Advanced

Operator + is in fact very slow compared to the set command (10 times according to my last test).

If you are working with large arrays you might want to consider putting that little extra effort in. Adding 1 element to an array:

_array1 = _array1 + [1]; // +
_array2 set [count _array2, 1]; // set

Adding elements from 1 array to another:

_array1 = [0,1,2,3,4];
_array2 = [0,1,2,3,4];
_arrayAdd = [5,6,7,8,9];
 
_array1 = _array1 + _arrayAdd; // +
// set:
for "_i" from 0 to ((count _arrayAdd) - 1) do
{
     _array2 set [count _array2, _arrayAdd select _i];
};