You are viewing an older version of the site. Click here to view
the latest version of this page. (This may be a dead link, if so, try the root page of the docs
here.)
Arrays are a way to group multiple pieces of data together into one variable. Arrays are created with
the {{function|array}} function, and can be manipulated with the array_* series of functions.
Arrays also function like a map, or an [http://en.wikipedia.org/wiki/Associative_array associative array].
==Array Creation==
To create an array, you use the {{function|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.
Copy Code
Alternatively, to create an empty associative array, you can use {{function|associative_array}}.
==Arrays stored in variables are references==
Once you create an array, you typically store it in a variable for further operations, like so:
Copy Code
If you need a distinct copy of an array, you can make one by calling {{function|array_get}} with just one parameter, the array.
Copy Code
===array_set using = (or assign())===
It is also possible to set the value of an array directly, with {{function|assign}}.
Copy Code
If you start to use multi dimensional arrays and associative arrays, this advantage becomes clearer:
Copy Code
===array_push using operators===
There is special syntax to do an array push as well. The following two blocks of code are equivalent.
Copy Code
Is the same as
Copy Code
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
Copy Code
In all cases, this is exactly equivalent to the following notation:
Copy Code
Much quicker. The only place this might be slightly confusing is the case of the single parameter
Copy Code
In typical fashion, the element
Copy Code
You can also chain gets:
Copy Code
In addition, you may use negative indices in either slot.
Copy Code
There are also two shortcuts when you want to select from the beginning of the array, or to the end of the array:
Copy Code
If the last index is less than the first index, an empty array is returned
Copy Code
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|cslice}}
function if you wish to do this dynamically.
Copy Code
==Associative Arrays==
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[0] 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.
Copy Code
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:
Copy Code
The other approach is to take an existing array, and set an out-of-order key into it, or a string key.
Copy Code
If you use {{function|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:
Copy Code
The above is exactly identical to:
Copy Code
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 {{function|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 {{function|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 {{function|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.
Copy Code
Otherwise, if you don't need the key, you may use the foreach normally.
Copy Code
Alternative syntax exists for {{function|foreach}}. See the documentation for more information.
If you want to convert an array back to a normal array, you may use the {{function|array_normalize}}
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.
Copy Code
Because in particular this behavior is different, if you aren't sure if an array is associative or not,
you can use the {{function|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
Copy Code
This works for all data types that implement the [[Builtin_Object_Info#ArrayAccess|ArrayAccess]] interface,
not just strings.
==Cloning an array==
To make a deep copy of an array, you can use the array clone mechanism.
Copy Code
Additionally, there is a shorthand syntax for the no argument array_get:
Copy Code
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 ==
Trailing commas are allowed in arrays (and actually all functions, however, this is most useful in arrays). For instance, you can do the following:
Copy Code
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.
{{LearningTrail}}
msg(array(1, 2, 3, 4));
// Outputs {1, 2, 3, 4}

1 {{function|msg}}({{function|array}}(1, 2, 3, 4));
2 // Outputs {1, 2, 3, 4}
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:
array @array = array(1, 2);
array @array2 = @array;
array_set(@array, 0, 2);
msg(@array); // Sends {2, 2}
msg(@array2); // Also sends {2, 2}

1 {{object|array}} @array = {{function|array}}(1, 2);
2 {{object|array}} @array2 = @array;
3 {{function|array_set}}(@array, 0, 2);
4 {{function|msg}}(@array); // Sends {2, 2}
5
6 {{function|msg}}(@array2); // Also sends {2, 2}
array @array = array(1, 2);
array @array2 = array_get(@array);
array_set(@array, 0, 2);
msg(@array); // Sends {2, 2}
msg(@array2); // Sends the original values: {1, 2}

1 {{object|array}} @array = {{function|array}}(1, 2);
2 {{object|array}} @array2 = {{function|array_get}}(@array);
3 {{function|array_set}}(@array, 0, 2);
4 {{function|msg}}(@array); // Sends {2, 2}
5
6 {{function|msg}}(@array2); // Sends the original values: {1, 2}
@array[0] = 'value'; // Equivalent to array_set(@array, 0, 'value')

1 @array[0] = 'value'; // Equivalent to array_set(@array, 0, 'value')
@array['value']['sub-value']['sub-sub-value'] = 'string';

1 @array['value']['sub-value']['sub-sub-value'] = 'string';
array @array = array();
@array[] = 1;
@array[] = 2;

1 {{object|array}} @array = {{function|array}}();
2 @array[] = 1;
3 @array[] = 2;
array @array = array();
array_push(@array, 1);
array_push(@array, 2);

1 {{object|array}} @array = {{function|array}}();
2 {{function|array_push}}(@array, 1);
3 {{function|array_push}}(@array, 2);
@array[] = 5
is an array push operation, and @newArray = @array[]
is an array clone operation.
==Retrieving values==
Now, the {{function|array_get}} function is how you retrieve a value from an existing array.
msg(array_get(array(1, 2, 3), 2));
// Outputs 3

1 {{function|msg}}({{function|array_get}}({{function|array}}(1, 2, 3), 2));
2 // Outputs 3
msg(array(1, 2, 3)[2]);

1 {{function|msg}}({{function|array}}(1, 2, 3)[2]);
array_get()
.
array_get(@array)
is equivalent to @array[]
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.
==Complex Retrievals==
In addition to the simple case of retrieving a single value from an array, MScript has support for negative indices, and array slices.
===Negative Indices===
Consider the following array:
@a = array('a', 'b', 'c', 'd', 'e');

1 @a = {{function|array}}('a', 'b', 'c', 'd', 'e');
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)]
===Array Slicing===
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:
msg(array('a', 'b', 'c', 'd', 'e')[1..2]); // Returns {b, c}
msg(array('a', 'b', 'c', 'd', 'e')[3..4]); // Returns {d, e}

1 {{function|msg}}({{function|array}}('a', 'b', 'c', 'd', 'e')[1..2]); // Returns {b, c}
2
3 {{function|msg}}({{function|array}}('a', 'b', 'c', 'd', 'e')[3..4]); // Returns {d, e}
msg(array('a', array(1, 2), 'c', 'd', 'e')[0..1][1][0]); // Returns 1

1 {{function|msg}}({{function|array}}('a', {{function|array}}(1, 2), 'c', 'd', 'e')[0..1][1][0]); // Returns 1
msg(array('a', 'b', 'c', 'd', 'e')[1..-1]); // Returns {b, c, d, e}
msg(array('a', 'b', 'c', 'd', 'e')[0..-1]); // Returns the whole array, equivalent to array(a, b, c, d, e)[]

1 {{function|msg}}({{function|array}}('a', 'b', 'c', 'd', 'e')[1..-1]); // Returns {b, c, d, e}
2
3 {{function|msg}}({{function|array}}('a', 'b', 'c', 'd', 'e')[0..-1]); // Returns the whole array, equivalent to array(a, b, c, d, e)[]
msg(array('a', 'b', 'c', 'd', 'e')[..1]); // Returns {a, b}, equivalent to [0..1]
msg(array('a', 'b', 'c', 'd', 'e')[2..]); // Returns {c, d, e}, equivalent to [2..-1] or [2..4]

1 {{function|msg}}({{function|array}}('a', 'b', 'c', 'd', 'e')[..1]); // Returns {a, b}, equivalent to [0..1]
2
3 {{function|msg}}({{function|array}}('a', 'b', 'c', 'd', 'e')[2..]); // Returns {c, d, e}, equivalent to [2..-1] or [2..4]
msg(array(1, 2, 3, 4, 5)[3..0]); // Returns {}

1 {{function|msg}}({{function|array}}(1, 2, 3, 4, 5)[3..0]); // Returns {}
array @a = array(1, 2, 3, 4, 5);
int @start = 0;
int @finish = 2;
msg(@a[cslice(@start, @finish)]); // Returns {1, 2, 3}

1 {{object|array}} @a = {{function|array}}(1, 2, 3, 4, 5);
2 {{object|int}} @start = 0;
3 {{object|int}} @finish = 2;
4 {{function|msg}}(@a[{{function|cslice}}(@start, @finish)]); // Returns {1, 2, 3}
array @arr = array('string key': 'value', 'string key 2': 'value');

1 {{object|array}} @arr = {{function|array}}('string key': 'value', 'string key 2': 'value');
msg(@arr['string key']); // Returns 'value'

1 {{function|msg}}(@arr['string key']); // Returns 'value'
// Create a new, normal array
array @arr = array(0, 1, 2, 3);
array_set(@arr, 4, 4); // Still normal, because this is the index array_push would have put it in anyways.
array_set(@arr, 0, 0); // Still normal, because this element already exists
array_push(@arr, 5); // Still normal, this value was pushed onto index 5. The array looks like this now: {0, 1, 2, 3, 4, 5}
// Note also that array_push doesn't accept a index, so we cannot create an associative array ever with it.
array_set(@arr, 'key', 'value'); // Now it is associative
array_set(@arr, 10, 'value'); // This also would make it associative

1 // Create a new, normal array
2
3 {{object|array}} @arr = {{function|array}}(0, 1, 2, 3);
4 {{function|array_set}}(@arr, 4, 4); // Still normal, because this is the index array_push would have put it in anyways.
5
6 {{function|array_set}}(@arr, 0, 0); // Still normal, because this element already exists
7
8 {{function|array_push}}(@arr, 5); // Still normal, this value was pushed onto index 5. The array looks like this now: {0, 1, 2, 3, 4, 5}
9
10 // Note also that array_push doesn't accept a index, so we cannot create an associative array ever with it.
11
12 {{function|array_set}}(@arr, 'key', 'value'); // Now it is associative
13
14 {{function|array_set}}(@arr, 10, 'value'); // This also would make it associative
array(0: 0, 5: 5, 1); // 1 gets inserted at index 6

1 {{function|array}}(0: 0, 5: 5, 1); // 1 gets inserted at index 6
array @arr = array();
array_set(@arr, 0, 0);
array_set(@arr, 5, 5);
array_push(@arr, 1);

1 {{object|array}} @arr = {{function|array}}();
2 {{function|array_set}}(@arr, 0, 0);
3 {{function|array_set}}(@arr, 5, 5);
4 {{function|array_push}}(@arr, 1);
array @arr = array(0, 1: 1, 2, 3: 3, a: 'a');
// Array looks like: {0: 0, 1: 1, 2: 2, 3: 3, a: a}
// Recall that array keys are always stored as string
foreach(string @key in array_keys(@arr)){ // array_keys returns {0, 1, 2, 3, a}
msg(@arr[@key]) #Messages the value
}

1 {{object|array}} @arr = {{function|array}}(0, 1: 1, 2, 3: 3, a: 'a');
2 // Array looks like: {0: 0, 1: 1, 2: 2, 3: 3, a: a}
3
4 // Recall that array keys are always stored as string
5
6 {{keyword|foreach}}({{object|string}} @key {{keyword|in}} {{function|array_keys}}(@arr)){ // array_keys returns {0, 1, 2, 3, a}
7
8 {{function|msg}}(@arr[@key]) #Messages the value
9
10 }
// Array keys are of type mixed, generally.
foreach(mixed @val in @arr){
msg(@val);
}

1 // Array keys are of type mixed, generally.
2
3 {{keyword|foreach}}({{object|mixed}} @val {{keyword|in}} @arr){
4 {{function|msg}}(@val);
5 }
array @arr = array(-1: -1, 0, 1, 2: 2);
msg(@arr[-1]); // Returns -1, NOT 2, like one might initially expect

1 {{object|array}} @arr = {{function|array}}(-1: -1, 0, 1, 2: 2);
2 {{function|msg}}(@arr[-1]); // Returns -1, NOT 2, like one might initially expect
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.
msg('Hello World!'[0]); // Returns 'H'
msg('Slice!'[2..]); // Returns 'ice!'

1 {{function|msg}}('Hello World!'[0]); // Returns 'H'
2
3 {{function|msg}}('Slice!'[2..]); // Returns 'ice!'
array @a = array(1, 2, 3);
array @b = array_get(@a);
@a[1] = 10;
msg(@a); // {1, 10, 3}
msg(@b); // {1, 2, 3} As you can see, the second array is unaffected by the assignment

1 {{object|array}} @a = {{function|array}}(1, 2, 3);
2 {{object|array}} @b = {{function|array_get}}(@a);
3 @a[1] = 10;
4 {{function|msg}}(@a); // {1, 10, 3}
5
6 {{function|msg}}(@b); // {1, 2, 3} As you can see, the second array is unaffected by the assignment
array @b = @a[];

1 {{object|array}} @b = @a[];
array(
1,
2,
4,
3,
);

1 {{function|array}}(
2 1,
3 2,
4 4,
5 3,
6 );
Find a bug in this page? Edit this page yourself, then submit a pull request.