Array: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
(subtraction not substraction)
(Now it's less messy and has more pertinent information.)
Line 1: Line 1:
==Description==
'''Array'''s are lists of [[Variable]]s of varying [[:Category:Types|variable types]]. Arrays can be both single-dimension and multi-dimensional.
An array is a list of items. Each item may be any of the [[:Category:Types|variable types]]. <br>
The items in an array are referred to as its '''elements'''.<br>
Arrays have an order. That is, any element in the array comes either before, or after, any other element in the array.


==Declaring Arrays==
Arrays are declared like this:<br>
_array = [elementOne, elementTwo, ..., lastElement]
Each element is either a literal of some type, or an expression of some type.


For example:<br>
== Working with arrays ==
_array = [1, "Word", (1 + [[damage]] [[player]])]
=== Creating (declaring) arrays ===
The first two elements are literals (a [[Number]] and a [[String]]), whilst the third is an expression (a [[Number]]).
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).  


====Arrays of Arrays====
<code>// Example of an empty array
You can have an array of arrays (aka a multi-dimensional array)
_myVariable = [];
_count = [[count]] _myVariable; // Output: 0


For example:
// Correct syntax
dudearray = [["Whatever", 2, 3, 1, 6], ["Whatever2", 2, 8, 3]]
_myFilledVariable = ["Weapon1","Weapon2"];
firstelement = dudearray select 0
_count = [[count]] _myVariable; // Output: 2
geteight = (dudearray select 1) select 2


firstelement would have the value ["Whatever",2,3,1,6]
// Error: Unexpected ","
_myErroneousArray = ["Weapon1","Weapon2","Weapon3",]; // The last element in an array must exclude the ","


geteight would have the value 8.
</code>


=== 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.


==Accessing elements==
<code>// Multi-dimensional array example
Every element in the array has an '''index'''. The index says what position the element is in the array. Indices are how elements are accessed. Indices begin at zero, and continue up to (size of array - 1).
_multiArray1 = [["Item1",1,2,3],["Item2",4,5,6]];
_count = [[count]] _multiArray1; // Output: 2
_count = [[count]] _multiArray1 select 0; // Output: 4
</code>
<code>// 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
</code>


The command for accessing elements is [[select|select]]. For example, suppose an array is <br>
=== Referencing and setting element values ===
_array = [soldier1, soldier2, soldier3]
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.  
Then, (_array [[select]] 0) is _soldier1, and (_array [[select]] 2) is soldier3.


===Looping to access elements===
<code>//Selecting an element from a single-dimensional array
In order to loop (or '''''iterate''''') through every element in an array, for any array, we have to know the array's size. <br>
_mySingleArray = ["Select 0","Select 1","Select 2"];
The command for finding an array's size is [[count]].
_myArrayElement = _mySingleArray select 0; // Output: "Select 0" (string)


===Index rounding===
// Selecting from multi-dimensional arrays
In OFP script, indices are rounded to the nearest whole number.
_myMultiArray = [["Array1Elem1","Array1Elem2"],["Array2Elem1","Array2Elem2"]];
A bounday case (X.5, where X is any whole number) rounds to the nearest '''even''' whole number
_selectFirst = _myMultiArray select 0; // Output: ["Array1Elem1","Array1Elem2"] (Array)
_count = count _selectFirst; // Output: 2


'''Boundary cases:'''<br>
_selectSecond = (_myMultiArray select 0) select 0; // Output: "Array1Elem1" (String)
-0.5 rounds up to 0<br>
</code>
-0.5 <= index <= 0.5 rounds to 0<br>
0.5 rounds down to 0<br>
0.5 < index < 1.5 rounds to 1<br>
1.5 rounds up to 2<br>
1.5 <= index <= 2.5 rounds to 2<br>
2.5 rounds down to 2<br>
2.5 < index < 3.5 rounds to 3<br>
3.5 rounds up to 4<br>


Other indices follow this pattern.
If you want to change the value of an element within an array, then the [[set]] function must be used.  
<code>// 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)
</code>


===When an Array index is out of Range===
If the index given by the [[set]] operator is out of bounds,
If a rounded index refers to a position in an array that is invalid:
* If the index rounded to a negative number, then an [[Error Zero Divisor]] message will be displayed in game.
*If the index is negative, an [[Error Zero Divisor]] error message will be displayed.
* 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 [[Nothing|null type]]
*If the index is positive, the returned value will be of the [[Nothing|null type]].


''Accesses which are out of bounds'':<br>
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.
_array = [];
_element = (_array select 0)


_array = ["element"];
=== Adding (appending) to arrays ===
_element = (_array select 1)
Appending to arrays is done by the use of the [[+]] operator in the same way that a string is concatenated.


_array = ["element"];
<code>// Example of adding two single-dimensional arrays
_element = (_array select -1)
_arrayOne = ["One"];
''Accesses which are in bounds'':
_arrayTwo = ["Two"];
_array = ["element"];
_arrayThree = _arrayOne + _arrayTwo; // Output: ["One","Two"];
_element = (_array select 0)
_count = count _arrayThree; // Output: 2
</code>


_array = ["element"];
===Looping to access elements===
_element = (_array select 0.1)
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.  


_array = ["element"];
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.  
_element = (_array select -0.3)


==Changing an array==
<code>//For Example
_myArray = ["One","Two","Three","Four"]; // 0 = "One", 1 = "Two", 2 = "Three", 3 = "Four"
_myCount = (count _myArray) -1;


There are two types of operations to change an array: operations which change the underlying array, and operations which return a new array, but leave the old array intact.
//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);
};


===Array references===
//The output will be:
//"One"
//"Two"
//"Three"
//"Four"
</code>


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.
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;).


Analogy using [[Object|Objects]]:<br>
<code>//forEach example
_unit1 = player<br>
_myArray = ["One","Two","Three","Four"]; // 0 = "One", 1 = "Two", 2 = "Three", 3 = "Four"
_unit2 = player
{
The commands (player [[setDamage]] 0.5), (_unit1 [[setDamage]] 0.5) and (_unit2 [[setDamage]] 0.5) all have the same effect, since they all refer to the same object (the [[player]]).
[[diag_log]](_x);
} forEach _myArray;


It is a similar case with arrays:<br>
// The output will be:
_array = [1,2,3]<br>
// "One"
_array1 = _array<br>
// "Two"
_array2 = _array
// "Three"
The commands (_array [[set]] [0, 7]), (_array1 [[set]] [0, 7]) and (_array2 [[set]] [0, 7]) all have the same effect, since they all refer to the same array.
// "Four"
 
</code>
===Setting elements===
Individual elements in an array can be set to different values.<br>
This is done via the [[set]] operator. '''It is important to declare the array before using the [[set]] operator.'''
 
The previous element at the specified index gets replaced with the new one.
 
Example:<br>
_array = [1,2,3]<br>
_array [[set]] [2, "Hello"]
Now, _array is [1, 2, "Hello"]. The 2nd index (which is the third element in the array, which was 3) gets replaced by "Hello".
 
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 [[Nothing|null type]]
 
Example:<br>
_array = [1]<br>
_array [[set]] [3, 4]
Now _array is [1, <Null>, <Null>, 4]
 
==Array copying, addition and subtraction==
 
Each of these commands returns a new array, and leaves the old array or arrays unchanged.


===Copying===
===Copying===
Line 130: Line 120:
Now _array and _array2 point to 2 different arrays, both of which have the contents [1,2,3].
Now _array and _array2 point to 2 different arrays, both of which have the contents [1,2,3].


===Addition===
This is done by the [[a plus b|+]] binary operator. It takes two arrays, and returns a new array which containes all of the first array, followed by all of the second array.
Example:<br>
_array1 = [player, 7, "String"]<br>
_array2 = [player, 2]<br>
_array3 = _array1 + _array2
After this _array3 refers to a new array which has the contents [player, 7, "String", player, 2]
Another example, using [[set]]:<br>
_array set [count _array, "String"];


===Subtraction===
===Subtraction===
Line 171: Line 149:
// _array will now contain: [["first","hello1"],["third","hello3"]]
// _array will now contain: [["first","hello1"],["third","hello3"]]
</code>
</code>
==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:'''<br>
-0.5 rounds up to 0<br>
-0.5 <= index <= 0.5 rounds to 0<br>
0.5 rounds down to 0<br>
0.5 < index < 1.5 rounds to 1<br>
1.5 rounds up to 2<br>
1.5 <= index <= 2.5 rounds to 2<br>
2.5 rounds down to 2<br>
2.5 < index < 3.5 rounds to 3<br>
3.5 rounds up to 4<br>
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 [[Nothing|null type]].
''Accesses which are out of bounds'':<br>
_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)
[[Category: Data Types]]
[[Category: Data Types]]

Revision as of 12:22, 5 May 2014

Arrays are lists of Variables 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.

// Example of adding two single-dimensional arrays _arrayOne = ["One"]; _arrayTwo = ["Two"]; _arrayThree = _arrayOne + _arrayTwo; // Output: ["One","Two"]; _count = count _arrayThree; // 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 _array and _array2 point to 2 different arrays, both of which have the contents [1,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"]]


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)