3.1.10 arrays
By default, Pyret users should use this library. If, however, you need a higher-performant but potentially less ergonomic array library, look at RawArray instead, which is primarily reserved for internal use and for building other libraries. However, do not use that library unless you really cannot get what you need out of this one.
Because arrays are mutable, equality is not straightforward. Learn more at equality.
3.1.10.1 Array Creation Functions
Creates an Array with the given elements. Note that Arrays are mutable, so comparisons using == (the operator for equal-always) will only return true on Arrays when they are also identical, regardless of their contents. To compare the elements, use equal-now/=~, and test with is=~.
check: a = [array: 1, 2, 3] a is a a is== a [array: 1, 2, 3] is=~ [array: 1, 2, 3] [array: 1, 2, 3] is-not== [array: 1, 2, 3] [array: 1, 2, 3] is-not [array: 1, 2, 3] end
Constructs an Array of length count, where every element is the value given as value.
Note that value is not copied, so, the elements of Arrays created with array-of will always be identical.
To create an array of arrays where each sub-array is independent of the other, use build-array.
Similar to raw-array-of.
check: arr = array-of(true, 2) arr is=~ [array: true, true] arr is-not [array: true, true] array-get-now(arr, 0) is<=> array-get-now(arr, 1) array-set-now(arr, 1, false) arr is=~ [array: true, false] arr-of-arrs = array-of(arr, 3) arr-of-arrs is=~ [array: [array: true, false], [array: true, false], [array: true, false]] array-set-now(arr, 0, false) arr-of-arrs is=~ [array: [array: false, false], [array: false, false], [array: false, false]] end
Constructs an array of length size, and fills it with the result of calling the function f with each index from 0 to size - 1.
Similar to raw-array-build.
check: fun sq(x): x * x end build-array(sq, 4) is=~ [array: sq(0), sq(1), sq(2), sq(3)] end check: fun build(n :: Number) -> Array<String>: array-of("_", 3) end a = build-array(build, 3) a is=~ [array: [array: "_", "_", "_"], [array: "_", "_", "_"], [array: "_", "_", "_"]] a.get-now(0).set-now(0, "X") a.get-now(1).set-now(1, "O") a is=~ [array: [array: "X", "_", "_"], [array: "_", "O", "_"], [array: "_", "_", "_"]] end
Converts a List to an Array containing the same elements in the same order.
Similar to raw-array-from-list.
check: array-from-list([list: 1, 2, 3]) is=~ [array: 1, 2, 3] end
3.1.10.2 Array Methods
Returns the value at the given index.
This method has a -now suffix because its answer can change from one call to the next if, for example, .set-now is used.
Using an index too large, negative, or not a whole number raises an error.
Similar to get and raw-array-get.
check: a = [array: "a", "b", "c"] a.get-now(0) is "a" a.get-now(1) is "b" a.get-now(4) raises "index" a.get-now(-1) raises "index" a.get-now(1.2) raises "index" end
Updates the value at the given index, returning Nothing.
The update is stateful, so all references to the array see the update. Hence the -now suffix; in the example below, calling a.get-now() at two different points in the program produces two different results.
Using an index too large, negative, or not a whole number raises an error.
Similar to raw-array-set.
check: a = [array: "a", "b", "c"] a.get-now(0) is "a" a.set-now(0, "d") a.get-now(0) is "d" b = a a.set-now(0, "f") a is=~ [array: "f", "b", "c"] b is=~ [array: "f", "b", "c"] c = b.set-now(0, 'z') c is nothing b.set-now(4, "hi") raises "index" end
Returns the length of the array. The length of an array is set when it is created and cannot be changed.
Similar to length and raw-array-length.
check: a = [array: "a", "b"] a.length() is 2 b = [array:] b.length() is 0 end
Applies function f to each element of self from left to right, constructing a new Array out of the elements for which f returned true.
Similar to filter and raw-array-filter.
check: a = [array: "apple", "banana", "plum"] p-words = a.filter({(s): string-contains(s, "p")}) p-words is=~ [array: "apple", "plum"] end
Creates a new array by applying f to each element of the array.
Similar to map and raw-array-map.
check: a = [array: "apple", "banana", "plum"] lengths = a.map(string-length) lengths is=~ [array: 5, 6, 4] end
Combines the elements in the array with a function that accumulates each element with an intermediate result. Has an argument order that works with for. The numeric argument to the accumulator is the index of the current element.
Similar to fold and raw-array-fold.
fun sum-even-minus-odd(a :: Array<Number>): fun is-even(n): (n / 2) == num-floor(n / 2) end fun sum-ith(sum-so-far :: Number, new-n :: Number, idx :: Number): if is-even(idx): sum-so-far + new-n else: sum-so-far - new-n end end a.fold(sum-ith, 0, 0) end check: sum-even-minus-odd([array: ]) is 0 sum-even-minus-odd([array: 1]) is 1 sum-even-minus-odd([array: 1, 2]) is (1 - 2) sum-even-minus-odd([array: 1, 2, 3]) is (1 + 3) - 2 sum-even-minus-odd([array: 1, 2, 3, 4]) is ((1 + 3) - (2 + 4)) end
Creates a new array with all the elements of the current array followed by all the elements of other.
Similar to append and raw-array-concat.
check: a = [array: "To", "be", "or"] a.concat([array: "not", "to", "be"]) is=~ [array: "To", "be", "or", "not", "to", "be"] a is=~ [array: "To", "be", "or"] a is-not=~ [array: "To", "be", "or", "not", "to", "be"] end
Returns a copy of the given array, such that corresponding elements in the result are Identical to those in the source array.
Similar to raw-array-duplicate.
data Person: p(ref name :: String, ref age :: Number) end check: ps1 = [array: p("Alice", 30), p("Bob", 40)] ps2 = ps1.duplicate() ps2.get-now(0) is ps1.get-now(0) ps2.get-now(1)!{age: 57} ps1.get-now(1)!age is 57 end
Sorts the given array in-place in ascending or descending order according to the asc parameter. Returns a reference to the original array, which will have its contents mutably updated.
Similar to raw-array-sort-nums.
check: a = [array: 3, 1, 4, 1, 5, 9, 2] asc = a.sort-nums(true) asc is<=> a a is=~ [array: 1, 1, 2, 3, 4, 5, 9] a.sort-nums(false) a is=~ [array: 9, 5, 4, 3, 2, 1, 1] end
Creates a new array containing the sorted contents of the given array. The sort order is determined by calling the key function on each element to get a number, and sorting the elements by their key value (in increasing key order if asc is true, decreasing if false). Ties are broken by the order in which the element is present in the initial array.
Similar to raw-array-sort-by.
check: a = [array: "let", "us", "go", "then", "you", "and", "i"] asc = a.sort-by(string-length, true) asc is=~ [array: "i", "us", "go", "let", "you", "and", "then"] asc is-not=~ a desc = a.sort-by(string-length, false) desc is=~ [array: "then", "let", "you", "and", "us", "go", "i"] a is=~ [array: "let", "us", "go", "then", "you", "and", "i"] end
Converts a Array to a List containing the same elements in the same order. This method has a -now suffix because its answer can change from one call to the next if, for example, .set-now is subsequently used.
Note that it does not recursively convert Arrays; only the top-level is converted.
Similar to raw-array-to-list.
check: a = [array: 1, 2, 3] a.to-list-now() is [list: 1, 2, 3] a2 = array-of([array:], 3) a2.to-list-now() is=~ [list: [array:], [array:], [array:]] a2.to-list-now() is-not=~ [list: [list:], [list:], [list:]] a.set-now(0, 5) a.to-list-now() is [list: 5, 2, 3] end
3.1.10.3 Array Functions
Equivalent to array.get-now(index).
check: a = [array: 0, 1, 2] array-get-now(a, 1) is 1 end
- array-set-now :: (
- array :: Array<a>,
- index :: Number,
- value :: a
- )
- -> Nothing
Equivalent to array.set-now(index, value).
check: a = array-of("a", 3) a is=~ [array: "a", "a", "a"] array-set-now(a, 1, "b") a is=~ [array: "a", "b", "a"] end
Equivalent to array.length().
check: a = array-of("a", 3) a is=~ [array: "a", "a", "a"] array-length(a) is 3 end
Equivalent to array.filter(f), with an argument order designed for for.
Equivalent to array.map(f), with an argument order designed for for.
- array-fold :: (
- f :: (b, a -> Number),
- init :: b,
- array :: Array<a>,
- start-index :: Number
- )
- -> b
Equivalent to array.fold(f, init, start-index), with an argument order designed for for.
Equivalent to array1.concat(array2).
Equivalent to array.duplicate().
Equivalent to array.sort-nums(asc).
import arrays as A check: a = [array: 3, 1, 4, 1, 5, 9, 2] asc = A.array-sort-nums(a, true) asc is<=> a a is=~ [array: 1, 1, 2, 3, 4, 5, 9] A.array-sort-nums(a, false) a is=~ [array: 9, 5, 4, 3, 2, 1, 1] end
- array-sort-by :: (
- array :: Array<a>,
- key :: (a -> Number),
- asc :: Boolean
- )
- -> Array<a>
Equivalent to array.sort-by(key, asc).
import arrays as A check: a = [array: "let", "us", "go", "then", "you", "and", "i"] asc = A.array-sort-by(a, string-length, true) asc is=~ [array: "i", "us", "go", "let", "you", "and", "then"] asc is-not=~ a desc = A.array-sort-by(a, string-length, false) desc is=~ [array: "then", "let", "you", "and", "us", "go", "i"] a is=~ [array: "let", "us", "go", "then", "you", "and", "i"] end
Equivalent to array.to-list-now().
check: a = array-of("a", 3) a is=~ [array: "a", "a", "a"] array-set-now(a, 1, "b") a is=~ [array: "a", "b", "a"] l = array-to-list-now(a) l is [list: "a", "b", "a"] end