Arrays are a way to group multiple pieces of data together into one variable. Arrays are created with
array() function, and can be manipulated with the array_* series of functions.
Arrays also function like a map, or an associative array.
- 1 Array Creation
- 2 Arrays stored in variables are references
- 3 Retrieving values
- 4 Complex Retrievals
- 5 Associative Arrays
- 6 Strings are sort of arrays
- 7 Cloning an array
- 8 Trailing Commas
To create an array, you use the
array() function. Sending no arguments creates an empty array,
or you can also send any number of arguments, and the array will be initialized with those elements.
Alternatively, to create an empty associative array, you can use
Arrays stored in variables are references
Once you create an array, you typically store it in a variable for further operations, like so:
assign(@array, array()). Once you have created an array like this, it is a reference to
the array itself, so if you were to assign it to another variable, and then set the value in that variable,
it will change the original array too. So, this would be the case:
If you need a distinct copy of an array, you can make one by calling
array_get() with just one parameter, the array.
array_set using = (or assign())
It is also possible to set the value of an array directly, with
If you start to use multi dimensional arrays and associative arrays, this advantage becomes clearer:
array_push using operators
There is special syntax to do an array push as well. The following two blocks of code are equivalent.
Is the same as
Note that this is different than the array clone operator, as it only works as an array push when used on the left hand side of an assignment, so
@array = 5
is an array push operation, and
@newArray = @array is an array clone operation.
array_get() function is how you retrieve a value from an existing array.
In all cases, this is exactly equivalent to the following notation:
Much quicker. The only place this might be slightly confusing is the case of the single parameter
array_get(@array) is equivalent to
It is worth noting that this square bracket notation is just a shortcut to using
array_get. In fact, the compiler
just uses a little magic under the covers to convert the bracket notation into the array_get notation. This means that if you
mess up the syntax somehow, you will still get an error for array_get, even if you aren't actually using that function. In
all the following examples, this guide will use the bracket notation, though you are free to use whichever method you like.
In addition to the simple case of retrieving a single value from an array, MScript has support for negative indices, and array slices.
Consider the following array:
In typical fashion, the element
a has an index of 0, and
e has an index of 4. These two elements could also be referenced with -5 and -1, respectively. Therefore, when considering indexes,
array(0, 1, 2, 3, 4) and
array(-5, -4, -3, -2, -1) are equivalent. Note that when counting with negative indices, -1 refers to the right most element, because -0 and 0 are the same thing. If this is confusing, think of it this way:
@array[multiply(@n, -1)] == @array[subtract(length(@array), @n)]
You can also get a sub array from an array with array slicing. Using the
.. notation, you can specify the range of elements you wish to include in the sub array.
Consider the following examples:
You can also chain gets:
In addition, you may use negative indices in either slot.
There are also two shortcuts when you want to select from the beginning of the array, or to the end of the array:
If the last index is less than the first index, an empty array is returned
Using this method of slicing requires the numbers to be hardcoded in, since this is a language construct. This makes it impossible to do dynamic slices using this method. Instead, you must use the
function if you wish to do this dynamically.
Arrays can also be used like an associative array. Typically, a simple array is indexed with zero-based, consecutive integers only. However, in an associative array, you may also use strings to index the array, or out-of-order integer offsets. Arrays by default operate in normal mode, and once they are switched to associative mode, certain features (namely negative indexes) will no longer work. Further, once an array is switched to associative mode, it is not possible to switch them back. Technically, all indexes are stored as strings. This means that @array and @array['0'] refer to the same thing. If you are familiar with other languages, this behavior is slightly different.
Creating an associative array
There are two ways to create an associative array. One is to create a completely new array, and the other is to take an existing array and turn it into an associative array.
This creates an array with two values. Note that it is required to put quotes around the key if it contains spaces. Otherwise, bare strings are acceptable (and usually preferred). To access the values, one would use:
The other approach is to take an existing array, and set an out-of-order key into it, or a string key.
If you use
array_push() on an associative array, it will take the largest integer + 1 in the array to be the next key.
Only strings are acceptable for keys. If you use another data type, it is interpreted perhaps differently than you would want, so note the following conventions:
- integers are taken as a string
- null is taken as an empty string:
- doubles are taken as a string
- true and false are taken as string '1' and '0', respectively.
- arrays will cause a runtime exception to be thrown.
One word of warning, the following will not do what you expect:
The above is exactly identical to:
Because we are explicitly creating an associative array here, an unlabeled value is essentially pushed on. 1 is pushed onto index 6 because when pushing a value onto an array, the highest integer index + 1 is used as the insertion point. If no integer indexes exist yet, it is inserted at 0, but if there are only negative indexes, it is inserted at one above the highest negative index.
Iterating Associative Arrays
As stated earlier, some functionality is not available to an associative array. Typically though, if you are
using an associative array, you aren't thinking of it as an ordered set of elements, you are thinking of it
more like an object that has properties. Iterating through all the elements doesn't usually assume any particular
order. This is where the
foreach() function comes in most handy. The elements are sorted according to
their natural ordering, that is, 1 comes before 2, a comes before b, etc, however there may be gaps in the
array, i.e. 0, 1, 4, 5, 10. Therefore looping through the array with
for() usually isn't useful. There
is one drawback to using foreach however, if you also need to know the key when iterating through, it isn't possible.
That's where the
array_keys() function comes in. This returns a normal array of all the keys in the array.
This array can be iterated against, and then used to pull out the value as well.
Otherwise, if you don't need the key, you may use the foreach normally.
Alternative syntax exists for
foreach(). See the documentation for more information.
If you want to convert an array back to a normal array, you may use the
function. This will return a new, non-associative array with the elements in their natural order,
starting with index 0. All information about the keys will be lost however.
Negative indexes don't work the same in an associative array, but that's not to say that negative indexes don't work at all. If you insert a negative index into the array, it will be available when you select it with a negative index.
Because in particular this behavior is different, if you aren't sure if an array is associative or not, you can use the
is_associative() function. Array slicing doesn't work either, because you might
in fact have a key with the index "0..1". If you do need to slice an associative array, and you don't care
about the keys, you can use the
array_normalize() function, and slice that. To copy an
associative array, use the empty bracket notation.
Strings are sort of arrays
Strings behave like an array of characters, to an extent. You can access a character in a string as if the array were an array of characters. Also, slicing works in a string as well, so you can get a substring easily also. Strings are immutable however, so trying to set a character in a string will not work.
This works for all data types that implement the ArrayAccess interface, not just strings.
Cloning an array
To make a deep copy of an array, you can use the array clone mechanism.
Additionally, there is a shorthand syntax for the no argument array_get:
Note that this is a deep copy operation, which means that the clone is recursive. So arrays within the array are also cloned.
Trailing commas are allowed in arrays (and actually all functions, however, this is most useful in arrays). For instance, you can do the following:
This is useful, because if you realize that you've misordered 3 and 4, you can cut and paste the entire line, and not have to worry about adding or removing a comma. Double commas are not allowed, however.