Array Library
The array library provides functionality for creating and manipulating arrays. Most of these functions are accessible as methods of array objects, as if they were classes. There are a few functions which are called through the "array" namespace.
array.new(size [, fill])
You can use array literals to create small arrays in MiniD, but sometimes you just need to be able to create an array of arbitrary size. This function will create an array of the given size. If you pass a value for the fill parameter, the new array will have every element set to it. Otherwise, it will be filled with null.
array.range(val1 [, val2 [, step]])
Creates a new array filled with integer values specified by the arguments. This is similar to the Python range() function, but is a little more intelligent when it comes to the direction of the range. Namely, if you give it indices where the ending index is less than the beginning, it will automatically use a negative step. In fact, the step value passed to this function must always be greater than 0; it simply defines the size of the step regardless of the direction the range goes in.
If only one argument is given, that argument specifies the noninclusive ending index, and the beginning index is assumed to be 0 and the step to be 1. This means array.range(5) will return [0, 1, 2, 3, 4] and array.range(-5) will return [0, -1, -2, -3, -4].
If two arguments are given, the first is the beginning inclusive index and the second is the ending noninclusive index. The step is again assumed to be 1. Examples: array.range(3, 8) yields [3, 4, 5, 6, 7]; array.range(2, -2) yields [2, 1, 0, -1]; and array.range(-10, -7) yields [-10, -9, -8].
Lastly, if three arguments are given, the first is the beginning inclusive index, the second the ending noninclusive index, and the third the step value. The step must be greater than 0; this function will automatically figure out that it needs to subtract the step if the ending index is less than the beginning index. Example: array.range(1, 20, 4) yields [1, 5, 9, 13, 17] and array.range(10, 0, 2) yields [10, 8, 6, 4, 2].
Methods
These are all called as "a.methodname()", where "a" is any array object.
a.sort()
Sorts the given array in ascending order. All the elements must be comparable with one another. Will call any opCmp metamethods. Returns the array itself.
a.reverse()
Reverses the elements in the given array. Returns the array itself.
a.dup()
Creates a copy of the given array. Only the array elements are copied, not any data that they point to.
a.length(newLength)
The length of an array can be retrieved using the # operator in MiniD, but in order to set the length, you must use this function. The array is resized (in place if possible) to the new length. All existing data is preserved, unless the length is reduced, where the existing data is truncated. If the length is increased, the new slots will be filled with null. The new length must be greater than or equal to 0.
a.opApply([direction])
This is an iterator bootstrap function which returns values which match the "container" expression in foreach statements. You can use this to iterate over an array:
foreach(i, v; a.opApply()) // ... foreach(i, v; a.opApply("reverse")) // iterate backwards
As the second example shows, passing in the string "reverse" as the second parameter will cause the iteration to run in reverse.
This iterator returns index-value pairs.
Since the array library works like methods, you shouldn't even have to call the opApply method explicitly. Simply put the array as the container of the foreach loop:
foreach(i, v; a) // ... foreach(i, v; a, "reverse") // iterate backwards
a.expand()
Returns all the elements of the array in order. In this way, you can "unpack" an array's values to pass as separate parameters to a function, or as return values, etc. Note that you probably shouldn't use this on really big arrays.
a.toString()
Returns a nice string representation of the array. This will format the array into a string that looks like a MiniD expression, like "[1, 2, 3]". Note that the elements of the array do not have their toString metamethods called, since that could lead to infinite loops if the array references itself directly or indirectly.
a.map(function)
Creates a new array the same length as the given array. Iterates over the given array, calling the function with each element, and assigns the result into the corresponding element of the new array. Returns the new array. So "[1, 2, 3, 4, 5].map(function(x) x * x)" will give the new array "[1, 4, 9, 16, 25]".
a.apply(function)
Iterates over the array, calling the function with each element of the array, and assigns the result of the function back into the corresponding array element. Returns the array it was called on. This is like map(), but works in-place instead of creating a new array.
a.reduce(function)
If the given array's length is 0, returns null. If the length is 1, returns the first element. Otherwise, calls the function with the first two elements as the parameters, gets that result, then calls the function with that result and the third element, gets that result, calls the function with that result and the fourth parameter... This continues until all the elements in the array have been iterated over. This seems confusing, but makes sense with a bit of illustration: "[1, 2, 3, 4, 5].reduce(function(a, b) a + b)" will sum all the elements of the array, since it's like writing ((((1 + 2) + 3) + 4) + 5). The first two elements are added, then the result is added to the third, and so on. The result of this function is the result of the application of the function to all the elements.
a.each(function)
Similar to table.each(), this is an alternate way of iterating over an array. The function is called once for each element, starting at the first element. The parameters to the function are the array as the context, then the index, and then the value. If the function returns false, iteration will stop and this function will return. This function returns the array on which it was called.
a.filter(function)
Creates a new array which holds only those elements for which the given function returned true when called with elements from the source array. The function is passed two arguments, the index and the value, and should return a boolean value. true means the given element should be included in the result, and false means it should be skipped. "[1, 2, "hi", 4.5, 6].filter(function(i, v) isInt(v))" would result in the array "[1, 2, 6]", as the filter function only returns true for integral elements.
a.find(value)
Performs a linear search for the value in the array. Returns -1 if it wasn't found, or its index if it was.
a.bsearch(value)
Performs a binary search for the value in the array. Because of the way binary search works, the array must be sorted for this search to work properly. Additionally, all the elements must be of the same type (they had to be for the sort to work in the first place). Returns -1 if the value wasn't found, or its index if it was.
a.pop([index])
This function can make it easy to use an array as a stack. Called with no parameters, it will remove the last element of the array and return it. Called with an index (which can be negative to mean from the end of the array), it will remove that element and shift all the other elements after it down a slot. In either case, if the array's length is 0, an error will be thrown.
