Version 2 of AGK introduced some new features to arrays, in particular the ability to sort, insert, and pass by reference into functions.
To maintain backwards compatibility arrays can still be defined with DIM, but version 2 introduces a new method of defining arrays that will become particularly important when defining them in types. Note that both DIM arrays and new style arrays perform exactly the same after they are declared so any functions mentioned here will also work on DIM arrays. The new method is mainly for consistency. The new method is as follows
The keyword DIM is not used and the size is moved to the end of the declaration. Arrays declared like this can only be declared once, unlike DIM arrays which can be declared multiple times to resize the array. The prefered method of resizing an array is now:
Where newSize can be any expression that could be assigned to a variable. An array length can also be discovered by using it as an expression like so
Note that because arrays start at index 0 and allow the size parameter as a valid index, an array defined as "DIM myArray" or "myArray as integer" would have 3 elements (0,1, and 2) but array.length will return "2" to reflect the size parameter that was used to declare it. Therefore an array of length 0 has one element and an empty array will return the length "-1".
For simplicity it may be beneficial to ignore index 0 at first, and assume that arrays start at index 1. This way the length parameter matches the number of assumed elements in the array and index 0 can be introduced as an additional element later. Some people used to use index 0 to store the length of the array for convenience, but with the new changes this is no longer necessary.
Elements can now be inserted and removed from arrays which will increase or decrease their size accordingly. For example
If an array is declared with a size parameter then elements will be inserted after the last existing element, for example
Elements can also be inserted at specific points in the array by adding an index parameter to the insert or remove command like so
Arrays can now be sorted using the .sort() command and searched using the .find(item) command. For example
.sort() will always sort in ascending order and .find(item) will only work on arrays that are in ascending order. If .find(item) cannot find the item you are looking for it will return "-1". You can sort arrays of Integers, Float, Strings, and Types. When sorting types the first variable of the type will be used to compare elements.
There is also a special insert command named .insertsorted(item) that will insert into a sorted array and maintain the array's ascending order so it can still be searched. For example, taking the array above
There are some additional array commands that don't fit in the above categories, they are .swap(index1,index2) to swap two elements in an array (including types and multidimenional arrays) and .reverse() to reverse the elements in an array.
Arrays can now be defined in types like so
The array could also be defined as an array of another type if desired so you can do things like this
Previously only types could be passed into functions and they were passed by value, meaning the type would be copied into a new variable which was then deleted at the end of the function. Now types can be passed by reference meaning that the variable being passed in will be modified by any changes in the function. For example
The same can also now be done with arrays
The new compiler is also very flexible about what you can pass into a function that takes a type or array, for example
To pass multidimensional arrays to functions use additional square brackets in the function declaration
and so on up to six dimensions. You can also pass sub arrays of multidimensional arrays into functions like so (using the functions above)
Also note that in these cases "myArray.length" would return 5, "myArray.length" would return 10 and myArray[0,0].length" would return 15, and each dimension can be resized individually
Arrays can be assigned values using the square bracket notation like so
If the number of elements being assigned is greater than the current array length then the array will be expanded to accommodate the new elements. If the number of elements is less than the current array length then the array length will remain the same and new elements will overwrite the beginning of the array, whilst the rest of the array remains unchanged
Arrays and types can also now be assigned directly to each other, doing so will copy the contents of the array or type to the other variable
Any sub arrays or sub types are also copied in their entirety, nothing will be shared with the new variable
Arrays can be converted to and from JSON strings by using the .toJSON() and .fromJSON(string) commands like so
When populating an array from a JSON string the array length will be adjusted to match the length of the array in the JSON string. You can also save and load the array to a JSON file by using the .save(filename) and .load(filename) commands like so
Types can also be converted to and from JSON strings like so
Types can contain other types or arrays, and will produce correctly nested JSON objects and arrays to match. There is no limitation on the contents of a type or array when converting it to JSON. When converting a JSON array to an AGK array then the array must only contain one type of variable, for example all integers, all floats, or all strings. There is no limit on a JSON object when converting it to an AGK type.
If a JSON object contains fields that are not in the AGK type being used to load it, then those fields will be ignored. If the AGK type contains fields that are not specified in the JSON object then those fields will be set to zero.
If a JSON object contains field names that are keywords in AGK then they cannot be directly loaded into an AGK type, since it won't be able to use those keywords as variable names. To overcome this you can use an underscore in front of the variable name in the AGK type and it will match JSON fields that don't have the underscore. For example
When using .toJSON() on a type, any variables that start with an underscore will have that underscore removed in the JSON string, so in the example above the JSON string produced by .toJSON() will contain the field "type" rather than the field "_type". Only the first underscore is removed, so if you actually wanted the JSON field name to begin with an underscore then add two underscores to the AGK type variable instead, i.e "__type" in AGK would be converted to "_type" in JSON.