Array: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
(new limit 10 mil)
No edit summary
Line 132: Line 132:
  (_b select 0) set [0, 4];
  (_b select 0) set [0, 4];
Now _b is an array [[4,1,1],[1,1,1]], while _a is still [[1,1,1],[1,1,1]], meaning that a sub-array gets copied (''deeply'') instead of copying a pointer to the same/original sub-array.
Now _b is an array [[4,1,1],[1,1,1]], while _a is still [[1,1,1],[1,1,1]], meaning that a sub-array gets copied (''deeply'') instead of copying a pointer to the same/original sub-array.
Take a note that arrays are as immutable as objects, assigning a variable to another variable referencing array, does nto copy it.
<code>
b = [1,2,3];
c = b;
b set [0,4];
diag_log b;
diag_log c;
// both will output [4,2,3]
</code>


===Subtraction===
===Subtraction===

Revision as of 03:59, 19 December 2016

From Arma 3 v1.55.133789 arrays are limited to maximum of 9,999,999 (sometimes 10,000,000) elements

Arrays are lists of items of varying variable types. Arrays can be both single-dimension and multi-dimensional.


Working with arrays

Creating (declaring) arrays

Declaration of an array refers to when an array is created in a script. An array can either be declared as empty, or it can be declared with already created elements. When an array is declared as empty as in the example below, it has no elements, and has an element count of 0. When referring to items within an array, the order runs from left-to-right, beginning with the number 0 (0,1,2,3).

// Example of an empty array _myVariable = []; _count = count _myVariable; // Output: 0

// Correct syntax _myFilledVariable = ["Weapon1","Weapon2"]; _count = count _myVariable; // Output: 2

// Error: Unexpected "," _myErroneousArray = ["Weapon1","Weapon2","Weapon3",]; // The last element in an array must exclude the ","

Multi-dimensional arrays

Multi-dimensional arrays are arrays within arrays. Associative arrays (i.e. "x" => [1,2,3],) are not a part of the language, however they can be approximated by creating a structure with a first element as a string and subsequent elements as arrays.

// Multi-dimensional array example _multiArray1 = [["Item1",1,2,3],["Item2",4,5,6]]; _count = count _multiArray1; // Output: 2 _count = count _multiArray1 select 0; // Output: 4 // Associative array approximation _assocTypeArray= [["Item1", ["My","Array","Elements"]],["Item2",["Smell","Like","Fromage"]]]; _count = count _assocTypeArray; // Output: 2 _count = count _assocTypeArray select 0; // Output: 2 _count = count ((_assocTypeArray select 0) select 1); // Output: 3

Referencing and setting element values

Unlike in other languages, referencing elements within script is performed with the use of the select function. As script functions allow stacking of functions, select can be used multiple times, provided that each select returns an array which can be selected.

//Selecting an element from a single-dimensional array _mySingleArray = ["Select 0","Select 1","Select 2"]; _myArrayElement = _mySingleArray select 0; // Output: "Select 0" (string)

// Selecting from multi-dimensional arrays _myMultiArray = [["Array1Elem1","Array1Elem2"],["Array2Elem1","Array2Elem2"]]; _selectFirst = _myMultiArray select 0; // Output: ["Array1Elem1","Array1Elem2"] (Array) _count = count _selectFirst; // Output: 2

_selectSecond = (_myMultiArray select 0) select 0; // Output: "Array1Elem1" (String)

If you want to change the value of an element within an array, then the set function must be used. // Set example _mySingleArray = ["Item1","Item2]; _myFirstItem = _mySingleArray select 0; // Output: "Item1" (String) _mySingleArray set [0,"Foo"]; // mySingleArray Output : ["Foo","Item2"] _myFirstItem = _mySingleArray select 0; // Output: "Foo" (String)

If the index given by the set operator is out of bounds,

  • If the index rounded to a negative number, then an Error Zero Divisor message will be displayed in game.
  • If the index rounded to a positive number, then the array will resize to incorporate the index as its last value. Each element between the last valid element, and the new set element, will be the null type

Array variables behave the same as Object references, and differently to String, Number and other variable types. An array variable holds a pointer to an array, or in other words, the location of an array. Any number of different variables can refer to the same array.

Adding (appending) to arrays

Appending to arrays is done by the use of the + operator in the same way that a string is concatenated. However, each time + is used, a new array is created. In Arma 3 "array + array" operation has been significantly optimised and is very fast. You can also add array to array using append command. To just add an element to an existing array in ArmA3 use pushBack.

// Example of adding two single-dimensional arrays _arrayOne = ["One"]; _arrayTwo = ["Two"]; _arrayThree = _arrayOne + _arrayTwo; // Output: ["One","Two"]; _arrayThree = _arrayOne append _arrayTwo; // Output: ["One","Two"]; _count = count _arrayThree; // Output: 2 _arrayOne pushBack "Two"; // ["One","Two"] _count = count _arrayOne // Output: 2

Looping to access elements

To loop through elements within an array, the for or forEach functions can be used. The for function is useful for when you want to loop over a finite number of items, such as if you have only 20 units and want to loop from 1 to 20. For can be used along with the count function to loop through an array of any length. forEach provides a function which doesn't require a number to be provided or a condition; it will take the input of an array and run through each element automatically for you.

In the for function, the user creates a variable inside quotes, such as "_x", which then refers to the current number as the for goes through the loop. In the forEach, the function creates a Magic variable called "_x", which refers to the current item in the array as the foreach goes through the loop.

//For Example _myArray = ["One","Two","Three","Four"]; // 0 = "One", 1 = "Two", 2 = "Three", 3 = "Four" _myCount = (count _myArray) -1;

//If we count the array, it will say "4", but we don't have an element "4" in the array, but we have 0,1,2,3. So remove 1 and we have the correct amount. for "_x" from 0 to _myCount do { _currentElement = _myArray select _x; // Selects 0,1,2,3 diag_log(_currentElement); };

//The output will be: //"One" //"Two" //"Three" //"Four"

The foreach loop has a strange syntax, but nonetheless performs the same function. The forEach function 'begins with a bracket rather than with the forEach function name ({}forEach;).

//forEach example _myArray = ["One","Two","Three","Four"]; // 0 = "One", 1 = "Two", 2 = "Three", 3 = "Four" { diag_log(_x); } forEach _myArray;

// The output will be: // "One" // "Two" // "Three" // "Four"

Copying

This is done by the + unary operator. It copies an array, and sets the array variable to point to this new array.

Example:

_array1 = [1,2,3]
_array2 = +_array1

Now _array1 and _array2 point to 2 different arrays, both of which have the contents [1,2,3].


Note that a deep copy is made using the + unary operator.

Example:

_a = [[1,1,1],[1,1,1]];
_b = +_a;
(_b select 0) set [0, 4];

Now _b is an array [[4,1,1],[1,1,1]], while _a is still [[1,1,1],[1,1,1]], meaning that a sub-array gets copied (deeply) instead of copying a pointer to the same/original sub-array.

Take a note that arrays are as immutable as objects, assigning a variable to another variable referencing array, does nto copy it. b = [1,2,3]; c = b; b set [0,4]; diag_log b; diag_log c; // both will output [4,2,3]

Subtraction

This is done by the - binary operator. It takes 2 arrays, and returns a new array that contains all of the items in the first array that were not in the second array.

Example:

_array1 = [1,2,player,2,"String","String",3]
_array2 = [2,player,"String"]
_array3 = _array1 - _array2

The result is that _array3 is a new array which has the contents [1, 3].

Note:

  • Subtracting an array from itself will always return an empty array [].
  • Nested arrays cannot be subtracted - i.e. the following does NOT work:
_a1 = [[1,1],[2,2],[3,3]];
_a2 = [[2,2]];
_a3 = _a1 - _a2; // will still return [[1,1],[2,2],[3,3]]

Workaround: You can remove nested arrays by first replacing them with a non array variable.

Example: _array = [["first","hello1"],["second","hello2"],["third","hello3"]]; _array set [1,-1]; _array = _array - [-1]; // _array will now contain: [["first","hello1"],["third","hello3"]]

Arma 3: Subtraction from MultiArrays in Arma 3 works:

_a1 = [[1,1],[2,2],[3,3]];
_a2 = [[2,2]];
_a3 = _a1 - _a2; // will return [[1,1],[3,3]]

Quirks and errors

Index rounding

In OFP script, indices are rounded to the nearest whole number. A bounday case (X.5, where X is any whole number) rounds to the nearest even whole number

Boundary cases:
-0.5 rounds up to 0
-0.5 <= index <= 0.5 rounds to 0
0.5 rounds down to 0
0.5 < index < 1.5 rounds to 1
1.5 rounds up to 2
1.5 <= index <= 2.5 rounds to 2
2.5 rounds down to 2
2.5 < index < 3.5 rounds to 3
3.5 rounds up to 4

Other indices follow this pattern.

When an Array index is out of Range

If a rounded index refers to a position in an array that is invalid:

  • If the index is negative, an Error Zero Divisor error message will be displayed.
  • If the index is positive, the returned value will be of the null type.

Accesses which are out of bounds:

_array = [];
_element = (_array select 0)
_array = ["element"];
_element = (_array select 1)
_array = ["element"];
_element = (_array select -1)

Accesses which are in bounds:

_array = ["element"];
_element = (_array select 0)
_array = ["element"];
_element = (_array select 0.1)
_array = ["element"];
_element = (_array select -0.3)