ic-mops 0.8.5 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/.mops/base@0.7.4/LICENSE +0 -208
- package/.mops/base@0.7.4/README.md +0 -64
- package/.mops/base@0.7.4/mops.toml +0 -5
- package/.mops/base@0.7.4/src/Array.mo +0 -686
- package/.mops/base@0.7.4/src/AssocList.mo +0 -203
- package/.mops/base@0.7.4/src/Blob.mo +0 -55
- package/.mops/base@0.7.4/src/Bool.mo +0 -44
- package/.mops/base@0.7.4/src/Buffer.mo +0 -1937
- package/.mops/base@0.7.4/src/CertifiedData.mo +0 -29
- package/.mops/base@0.7.4/src/Char.mo +0 -67
- package/.mops/base@0.7.4/src/Debug.mo +0 -15
- package/.mops/base@0.7.4/src/Deque.mo +0 -75
- package/.mops/base@0.7.4/src/Error.mo +0 -41
- package/.mops/base@0.7.4/src/ExperimentalCycles.mo +0 -51
- package/.mops/base@0.7.4/src/ExperimentalInternetComputer.mo +0 -36
- package/.mops/base@0.7.4/src/ExperimentalStableMemory.mo +0 -121
- package/.mops/base@0.7.4/src/Float.mo +0 -150
- package/.mops/base@0.7.4/src/Func.mo +0 -38
- package/.mops/base@0.7.4/src/Hash.mo +0 -83
- package/.mops/base@0.7.4/src/HashMap.mo +0 -229
- package/.mops/base@0.7.4/src/Heap.mo +0 -113
- package/.mops/base@0.7.4/src/Int.mo +0 -150
- package/.mops/base@0.7.4/src/Int16.mo +0 -159
- package/.mops/base@0.7.4/src/Int32.mo +0 -160
- package/.mops/base@0.7.4/src/Int64.mo +0 -161
- package/.mops/base@0.7.4/src/Int8.mo +0 -160
- package/.mops/base@0.7.4/src/Iter.mo +0 -220
- package/.mops/base@0.7.4/src/IterType.mo +0 -7
- package/.mops/base@0.7.4/src/List.mo +0 -433
- package/.mops/base@0.7.4/src/Nat.mo +0 -75
- package/.mops/base@0.7.4/src/Nat16.mo +0 -146
- package/.mops/base@0.7.4/src/Nat32.mo +0 -146
- package/.mops/base@0.7.4/src/Nat64.mo +0 -146
- package/.mops/base@0.7.4/src/Nat8.mo +0 -146
- package/.mops/base@0.7.4/src/None.mo +0 -19
- package/.mops/base@0.7.4/src/Option.mo +0 -160
- package/.mops/base@0.7.4/src/Order.mo +0 -46
- package/.mops/base@0.7.4/src/Prelude.mo +0 -33
- package/.mops/base@0.7.4/src/Principal.mo +0 -58
- package/.mops/base@0.7.4/src/RBTree.mo +0 -218
- package/.mops/base@0.7.4/src/Random.mo +0 -188
- package/.mops/base@0.7.4/src/Result.mo +0 -210
- package/.mops/base@0.7.4/src/Stack.mo +0 -40
- package/.mops/base@0.7.4/src/Text.mo +0 -615
- package/.mops/base@0.7.4/src/Time.mo +0 -37
- package/.mops/base@0.7.4/src/Trie.mo +0 -1200
- package/.mops/base@0.7.4/src/TrieMap.mo +0 -180
- package/.mops/base@0.7.4/src/TrieSet.mo +0 -97
- package/.mops/base@0.8.3/LICENSE +0 -208
- package/.mops/base@0.8.3/README.md +0 -64
- package/.mops/base@0.8.3/mops.toml +0 -6
- package/.mops/base@0.8.3/src/Array.mo +0 -717
- package/.mops/base@0.8.3/src/AssocList.mo +0 -404
- package/.mops/base@0.8.3/src/Blob.mo +0 -212
- package/.mops/base@0.8.3/src/Bool.mo +0 -44
- package/.mops/base@0.8.3/src/Buffer.mo +0 -2660
- package/.mops/base@0.8.3/src/CertifiedData.mo +0 -53
- package/.mops/base@0.8.3/src/Char.mo +0 -65
- package/.mops/base@0.8.3/src/Debug.mo +0 -56
- package/.mops/base@0.8.3/src/Deque.mo +0 -243
- package/.mops/base@0.8.3/src/Error.mo +0 -68
- package/.mops/base@0.8.3/src/ExperimentalCycles.mo +0 -151
- package/.mops/base@0.8.3/src/ExperimentalInternetComputer.mo +0 -60
- package/.mops/base@0.8.3/src/ExperimentalStableMemory.mo +0 -348
- package/.mops/base@0.8.3/src/Float.mo +0 -843
- package/.mops/base@0.8.3/src/Func.mo +0 -46
- package/.mops/base@0.8.3/src/Hash.mo +0 -82
- package/.mops/base@0.8.3/src/HashMap.mo +0 -457
- package/.mops/base@0.8.3/src/Heap.mo +0 -233
- package/.mops/base@0.8.3/src/Int.mo +0 -365
- package/.mops/base@0.8.3/src/Int16.mo +0 -521
- package/.mops/base@0.8.3/src/Int32.mo +0 -522
- package/.mops/base@0.8.3/src/Int64.mo +0 -522
- package/.mops/base@0.8.3/src/Int8.mo +0 -522
- package/.mops/base@0.8.3/src/Iter.mo +0 -227
- package/.mops/base@0.8.3/src/IterType.mo +0 -7
- package/.mops/base@0.8.3/src/List.mo +0 -930
- package/.mops/base@0.8.3/src/Nat.mo +0 -305
- package/.mops/base@0.8.3/src/Nat16.mo +0 -144
- package/.mops/base@0.8.3/src/Nat32.mo +0 -144
- package/.mops/base@0.8.3/src/Nat64.mo +0 -144
- package/.mops/base@0.8.3/src/Nat8.mo +0 -144
- package/.mops/base@0.8.3/src/None.mo +0 -19
- package/.mops/base@0.8.3/src/Option.mo +0 -154
- package/.mops/base@0.8.3/src/Order.mo +0 -46
- package/.mops/base@0.8.3/src/Prelude.mo +0 -33
- package/.mops/base@0.8.3/src/Principal.mo +0 -249
- package/.mops/base@0.8.3/src/RBTree.mo +0 -681
- package/.mops/base@0.8.3/src/Random.mo +0 -270
- package/.mops/base@0.8.3/src/Result.mo +0 -209
- package/.mops/base@0.8.3/src/Stack.mo +0 -93
- package/.mops/base@0.8.3/src/Text.mo +0 -761
- package/.mops/base@0.8.3/src/Time.mo +0 -36
- package/.mops/base@0.8.3/src/Timer.mo +0 -62
- package/.mops/base@0.8.3/src/Trie.mo +0 -1603
- package/.mops/base@0.8.3/src/TrieMap.mo +0 -392
- package/.mops/base@0.8.3/src/TrieSet.mo +0 -148
- package/network.txt +0 -1
|
@@ -1,686 +0,0 @@
|
|
|
1
|
-
/// Provides extended utility functions on Arrays. Note the difference between
|
|
2
|
-
/// mutable and non-mutable arrays below.
|
|
3
|
-
///
|
|
4
|
-
/// WARNING: If you are looking for a list that can grow and shrink in size,
|
|
5
|
-
/// it is recommended you use either the Buffer class or the List class for
|
|
6
|
-
/// those purposes. Arrays must be created with a fixed size.
|
|
7
|
-
///
|
|
8
|
-
/// Import from the base library to use this module.
|
|
9
|
-
/// ```motoko name=import
|
|
10
|
-
/// import Array "mo:base/Array";
|
|
11
|
-
/// ```
|
|
12
|
-
|
|
13
|
-
import I "IterType";
|
|
14
|
-
import Option "Option";
|
|
15
|
-
import Order "Order";
|
|
16
|
-
import Prim "mo:⛔";
|
|
17
|
-
import Result "Result";
|
|
18
|
-
|
|
19
|
-
module {
|
|
20
|
-
/// Create a mutable array with `size` copies of the initial value.
|
|
21
|
-
///
|
|
22
|
-
/// ```motoko include=import
|
|
23
|
-
/// let array = Array.init<Nat>(4, 2);
|
|
24
|
-
/// ```
|
|
25
|
-
///
|
|
26
|
-
/// Runtime: O(size)
|
|
27
|
-
/// Space: O(size)
|
|
28
|
-
public func init<X>(size : Nat, initValue : X) : [var X] =
|
|
29
|
-
Prim.Array_init<X>(size, initValue);
|
|
30
|
-
|
|
31
|
-
/// Create an immutable array of size `size`. Each element at index i
|
|
32
|
-
/// is created by applying `generator` to i.
|
|
33
|
-
///
|
|
34
|
-
/// ```motoko include=import
|
|
35
|
-
/// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);
|
|
36
|
-
/// ```
|
|
37
|
-
///
|
|
38
|
-
/// Runtime: O(size)
|
|
39
|
-
/// Space: O(size)
|
|
40
|
-
///
|
|
41
|
-
/// *Runtime and space assumes that `generator` runs in O(1) time and space.
|
|
42
|
-
public func tabulate<X>(size : Nat, generator : Nat -> X) : [X] =
|
|
43
|
-
Prim.Array_tabulate<X>(size, generator);
|
|
44
|
-
|
|
45
|
-
/// Create a mutable array of size `size`. Each element at index i
|
|
46
|
-
/// is created by applying `generator` to i.
|
|
47
|
-
///
|
|
48
|
-
/// ```motoko include=import
|
|
49
|
-
/// let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);
|
|
50
|
-
/// array[2] := 0;
|
|
51
|
-
/// array
|
|
52
|
-
/// ```
|
|
53
|
-
///
|
|
54
|
-
/// Runtime: O(size)
|
|
55
|
-
/// Space: O(size)
|
|
56
|
-
///
|
|
57
|
-
/// *Runtime and space assumes that `generator` runs in O(1) time and space.
|
|
58
|
-
public func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X] {
|
|
59
|
-
// FIXME add this as a primitive in the RTS
|
|
60
|
-
if (size == 0) { return [var] };
|
|
61
|
-
let array = Prim.Array_init<X>(size, generator 0);
|
|
62
|
-
var i = 0;
|
|
63
|
-
while (i < size) {
|
|
64
|
-
array[i] := generator i;
|
|
65
|
-
i += 1;
|
|
66
|
-
};
|
|
67
|
-
array
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/// Transforms a mutable array into an immutable array.
|
|
71
|
-
///
|
|
72
|
-
/// ```motoko include=import
|
|
73
|
-
///
|
|
74
|
-
/// let varArray = [var 0, 1, 2];
|
|
75
|
-
/// varArray[2] := 3;
|
|
76
|
-
/// let array = Array.freeze<Nat>(varArray);
|
|
77
|
-
/// ```
|
|
78
|
-
///
|
|
79
|
-
/// Runtime: O(size)
|
|
80
|
-
///
|
|
81
|
-
/// Space: O(1)
|
|
82
|
-
public func freeze<X>(varArray : [var X]) : [X] =
|
|
83
|
-
Prim.Array_tabulate<X>(varArray.size(), func i = varArray[i]);
|
|
84
|
-
|
|
85
|
-
/// Transforms an immutable array into a mutable array.
|
|
86
|
-
///
|
|
87
|
-
/// ```motoko include=import
|
|
88
|
-
///
|
|
89
|
-
/// let array = [0, 1, 2];
|
|
90
|
-
/// let varArray = Array.thaw<Nat>(array);
|
|
91
|
-
/// varArray[2] := 3;
|
|
92
|
-
/// varArray
|
|
93
|
-
/// ```
|
|
94
|
-
///
|
|
95
|
-
/// Runtime: O(size)
|
|
96
|
-
///
|
|
97
|
-
/// Space: O(1)
|
|
98
|
-
public func thaw<A>(array : [A]) : [var A] {
|
|
99
|
-
let size = array.size();
|
|
100
|
-
if (size == 0) {
|
|
101
|
-
return [var];
|
|
102
|
-
};
|
|
103
|
-
let newArray = Prim.Array_init<A>(size, array[0]);
|
|
104
|
-
var i = 0;
|
|
105
|
-
while (i < size) {
|
|
106
|
-
newArray[i] := array[i];
|
|
107
|
-
i += 1;
|
|
108
|
-
};
|
|
109
|
-
newArray
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/// Tests if two arrays contain equal values (i.e. they represent the same
|
|
113
|
-
/// list of elements). Uses `equal` to compare elements in the arrays.
|
|
114
|
-
///
|
|
115
|
-
/// ```motoko include=import
|
|
116
|
-
/// // Use the equal function from the Nat module to compare Nats
|
|
117
|
-
/// import {equal} "mo:base/Nat";
|
|
118
|
-
///
|
|
119
|
-
/// let array1 = [0, 1, 2, 3];
|
|
120
|
-
/// let array2 = [0, 1, 2, 3];
|
|
121
|
-
/// Array.equal(array1, array2, equal)
|
|
122
|
-
/// ```
|
|
123
|
-
///
|
|
124
|
-
/// Runtime: O(size1 + size2)
|
|
125
|
-
///
|
|
126
|
-
/// Space: O(1)
|
|
127
|
-
///
|
|
128
|
-
/// *Runtime and space assumes that `equal` runs in O(1) time and space.
|
|
129
|
-
public func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool {
|
|
130
|
-
let size1 = array1.size();
|
|
131
|
-
let size2 = array2.size();
|
|
132
|
-
if (size1 != size2) {
|
|
133
|
-
return false;
|
|
134
|
-
};
|
|
135
|
-
var i = 0;
|
|
136
|
-
while (i < size1) {
|
|
137
|
-
if (not equal(array1[i], array2[i])) {
|
|
138
|
-
return false;
|
|
139
|
-
};
|
|
140
|
-
i += 1;
|
|
141
|
-
};
|
|
142
|
-
return true;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/// Returns the first value in `array` for which `predicate` returns true.
|
|
146
|
-
/// If no element satisfies the predicate, returns null.
|
|
147
|
-
///
|
|
148
|
-
/// ```motoko include=import
|
|
149
|
-
/// let array = [1, 9, 4, 8];
|
|
150
|
-
/// Array.find<Nat>(array, func x = x > 8)
|
|
151
|
-
/// ```
|
|
152
|
-
/// Runtime: O(size)
|
|
153
|
-
///
|
|
154
|
-
/// Space: O(1)
|
|
155
|
-
///
|
|
156
|
-
/// *Runtime and space assumes that `predicate` runs in O(1) time and space.
|
|
157
|
-
public func find<X>(array : [X], predicate : X -> Bool) : ?X {
|
|
158
|
-
for (element in array.vals()) {
|
|
159
|
-
if (predicate element) {
|
|
160
|
-
return ?element;
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
return null;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
/// Create a new array by appending the values of `array1` and `array2`.
|
|
167
|
-
/// @deprecated `Array.append` copies its arguments and has linear complexity;
|
|
168
|
-
/// when used in a loop, consider using a `Buffer`, and `Buffer.append`, instead.
|
|
169
|
-
///
|
|
170
|
-
/// ```motoko include=import
|
|
171
|
-
/// let array1 = [1, 2, 3];
|
|
172
|
-
/// let array2 = [4, 5, 6];
|
|
173
|
-
/// Array.append<Nat>(array1, array2)
|
|
174
|
-
/// ```
|
|
175
|
-
/// Runtime: O(size1 + size2)
|
|
176
|
-
///
|
|
177
|
-
/// Space: O(size1 + size2)
|
|
178
|
-
public func append<X>(array1 : [X], array2 : [X]) : [X] {
|
|
179
|
-
let size1 = array1.size();
|
|
180
|
-
let size2 = array2.size();
|
|
181
|
-
Prim.Array_tabulate<X>(size1 + size2, func i {
|
|
182
|
-
if (i < size1) {
|
|
183
|
-
array1[i];
|
|
184
|
-
} else {
|
|
185
|
-
array2[i - size1];
|
|
186
|
-
};
|
|
187
|
-
});
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// FIXME this example stack overflows. Should test with new implementation of sortInPlace
|
|
191
|
-
/// Sorts the elements in the array according to `compare`.
|
|
192
|
-
/// Sort is deterministic and stable.
|
|
193
|
-
///
|
|
194
|
-
/// ```motoko include=import
|
|
195
|
-
/// import Nat "mo:base/Nat";
|
|
196
|
-
///
|
|
197
|
-
/// let array = [4, 2, 6];
|
|
198
|
-
/// Array.sort(array, Nat.compare)
|
|
199
|
-
/// ```
|
|
200
|
-
/// Runtime: O(size * log(size))
|
|
201
|
-
///
|
|
202
|
-
/// Space: O(size)
|
|
203
|
-
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
|
|
204
|
-
public func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X] {
|
|
205
|
-
let temp : [var X] = thaw(array);
|
|
206
|
-
sortInPlace(temp, compare);
|
|
207
|
-
freeze(temp)
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
/// Sorts the elements in the array, __in place__, according to `compare`.
|
|
211
|
-
/// Sort is deterministic, stable, and in-place.
|
|
212
|
-
///
|
|
213
|
-
/// ```motoko include=import
|
|
214
|
-
///
|
|
215
|
-
/// import {compare} "mo:base/Nat";
|
|
216
|
-
///
|
|
217
|
-
/// let array = [var 4, 2, 6];
|
|
218
|
-
/// Array.sortInPlace(array, compare);
|
|
219
|
-
/// array
|
|
220
|
-
/// ```
|
|
221
|
-
/// Runtime: O(size * log(size))
|
|
222
|
-
///
|
|
223
|
-
/// Space: O(size)
|
|
224
|
-
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
|
|
225
|
-
public func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order) {
|
|
226
|
-
// Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.
|
|
227
|
-
let size = array.size();
|
|
228
|
-
if (size == 0) {
|
|
229
|
-
return;
|
|
230
|
-
};
|
|
231
|
-
let scratchSpace = Prim.Array_init<X>(size, array[0]);
|
|
232
|
-
|
|
233
|
-
let sizeDec = size - 1 : Nat;
|
|
234
|
-
var currSize = 1; // current size of the subarrays being merged
|
|
235
|
-
// when the current size == size, the array has been merged into a single sorted array
|
|
236
|
-
while (currSize < size) {
|
|
237
|
-
var leftStart = 0; // selects the current left subarray being merged
|
|
238
|
-
while (leftStart < sizeDec) {
|
|
239
|
-
let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {
|
|
240
|
-
leftStart + currSize - 1;
|
|
241
|
-
} else { sizeDec };
|
|
242
|
-
let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {
|
|
243
|
-
leftStart + (2 * currSize) - 1;
|
|
244
|
-
} else { sizeDec };
|
|
245
|
-
|
|
246
|
-
// Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]
|
|
247
|
-
var left = leftStart;
|
|
248
|
-
var right = mid + 1;
|
|
249
|
-
var nextSorted = leftStart;
|
|
250
|
-
while (left < mid + 1 and right < rightEnd + 1) {
|
|
251
|
-
let leftElement = array[left];
|
|
252
|
-
let rightElement = array[right];
|
|
253
|
-
switch (compare(leftElement, rightElement)) {
|
|
254
|
-
case (#less or #equal) {
|
|
255
|
-
scratchSpace[nextSorted] := leftElement;
|
|
256
|
-
left += 1;
|
|
257
|
-
};
|
|
258
|
-
case (#greater) {
|
|
259
|
-
scratchSpace[nextSorted] := rightElement;
|
|
260
|
-
right += 1;
|
|
261
|
-
};
|
|
262
|
-
};
|
|
263
|
-
nextSorted += 1;
|
|
264
|
-
};
|
|
265
|
-
while (left < mid + 1) {
|
|
266
|
-
scratchSpace[nextSorted] := array[left];
|
|
267
|
-
nextSorted += 1;
|
|
268
|
-
left += 1;
|
|
269
|
-
};
|
|
270
|
-
while (right < rightEnd + 1) {
|
|
271
|
-
scratchSpace[nextSorted] := array[right];
|
|
272
|
-
nextSorted += 1;
|
|
273
|
-
right += 1;
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
// Copy over merged elements
|
|
277
|
-
var i = leftStart;
|
|
278
|
-
while (i < rightEnd + 1) {
|
|
279
|
-
array[i] := scratchSpace[i];
|
|
280
|
-
i += 1;
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
leftStart += 2 * currSize;
|
|
284
|
-
};
|
|
285
|
-
currSize *= 2;
|
|
286
|
-
};
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
/// Creates a new array by reversing the order of elements in `array`.
|
|
290
|
-
///
|
|
291
|
-
/// ```motoko include=import
|
|
292
|
-
///
|
|
293
|
-
/// let array = [10, 11, 12];
|
|
294
|
-
///
|
|
295
|
-
/// Array.reverse(array)
|
|
296
|
-
/// ```
|
|
297
|
-
///
|
|
298
|
-
/// Runtime: O(size)
|
|
299
|
-
///
|
|
300
|
-
/// Space: O(1)
|
|
301
|
-
public func reverse<X>(array : [X]) : [X] {
|
|
302
|
-
let size = array.size();
|
|
303
|
-
Prim.Array_tabulate<X>(size, func i = array[size - i - 1]);
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
/// Creates a new array by applying `f` to each element in `array`. `f` "maps"
|
|
307
|
-
/// each element it is applied to of type `X` to an element of type `Y`.
|
|
308
|
-
/// Retains original ordering of elements.
|
|
309
|
-
///
|
|
310
|
-
/// ```motoko include=import
|
|
311
|
-
///
|
|
312
|
-
/// let array = [0, 1, 2, 3];
|
|
313
|
-
/// Array.map<Nat, Nat>(array, func x = x * 3)
|
|
314
|
-
/// ```
|
|
315
|
-
///
|
|
316
|
-
/// Runtime: O(size)
|
|
317
|
-
///
|
|
318
|
-
/// Space: O(size)
|
|
319
|
-
///
|
|
320
|
-
/// *Runtime and space assumes that `f` runs in O(1) time and space.
|
|
321
|
-
public func map<X, Y>(array : [X], f : X -> Y) : [Y] =
|
|
322
|
-
Prim.Array_tabulate<Y>(array.size(), func i = f(array[i]));
|
|
323
|
-
|
|
324
|
-
/// Creates a new array by applying `predicate` to every element
|
|
325
|
-
/// in `array`, retaining the elements for which `predicate` returns true.
|
|
326
|
-
///
|
|
327
|
-
/// ```motoko include=import
|
|
328
|
-
/// let array = [4, 2, 6, 1, 5];
|
|
329
|
-
/// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);
|
|
330
|
-
/// ```
|
|
331
|
-
/// Runtime: O(size)
|
|
332
|
-
///
|
|
333
|
-
/// Space: O(size)
|
|
334
|
-
/// *Runtime and space assumes that `predicate` runs in O(1) time and space.
|
|
335
|
-
public func filter<X>(array : [X], predicate : X -> Bool) : [X] {
|
|
336
|
-
var count = 0;
|
|
337
|
-
let keep =
|
|
338
|
-
Prim.Array_tabulate<Bool>(
|
|
339
|
-
array.size(),
|
|
340
|
-
func i {
|
|
341
|
-
if (predicate(array[i])) {
|
|
342
|
-
count += 1;
|
|
343
|
-
true
|
|
344
|
-
} else {
|
|
345
|
-
false
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
);
|
|
349
|
-
var nextKeep = 0;
|
|
350
|
-
Prim.Array_tabulate<X>(
|
|
351
|
-
count,
|
|
352
|
-
func _ {
|
|
353
|
-
while (not keep[nextKeep]) {
|
|
354
|
-
nextKeep += 1;
|
|
355
|
-
};
|
|
356
|
-
nextKeep += 1;
|
|
357
|
-
array[nextKeep - 1];
|
|
358
|
-
}
|
|
359
|
-
)
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
// FIXME the arguments ordering to the higher order function are flipped
|
|
363
|
-
// between this and the buffer class
|
|
364
|
-
// probably can't avoid breaking changes at some point
|
|
365
|
-
/// Creates a new array by applying `f` to each element in `array` and its index.
|
|
366
|
-
/// Retains original ordering of elements.
|
|
367
|
-
///
|
|
368
|
-
/// ```motoko include=import
|
|
369
|
-
///
|
|
370
|
-
/// let array = [10, 10, 10, 10];
|
|
371
|
-
/// Array.mapEntries<Nat, Nat>(array, func (i, x) = i * x)
|
|
372
|
-
/// ```
|
|
373
|
-
///
|
|
374
|
-
/// Runtime: O(size)
|
|
375
|
-
///
|
|
376
|
-
/// Space: O(size)
|
|
377
|
-
///
|
|
378
|
-
/// *Runtime and space assumes that `f` runs in O(1) time and space.
|
|
379
|
-
public func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y] =
|
|
380
|
-
Prim.Array_tabulate<Y>(array.size(), func i = f(array[i], i));
|
|
381
|
-
|
|
382
|
-
/// Creates a new array by applying `f` to each element in `array`,
|
|
383
|
-
/// and keeping all non-null elements. The ordering is retained.
|
|
384
|
-
///
|
|
385
|
-
/// ```motoko include=import
|
|
386
|
-
/// import {toText} "mo:base/Nat";
|
|
387
|
-
///
|
|
388
|
-
/// let array = [4, 2, 0, 1];
|
|
389
|
-
/// let newArray =
|
|
390
|
-
/// Array.mapFilter<Nat, Text>( // mapping from Nat to Text values
|
|
391
|
-
/// array,
|
|
392
|
-
/// func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null
|
|
393
|
-
/// );
|
|
394
|
-
/// ```
|
|
395
|
-
/// Runtime: O(size)
|
|
396
|
-
///
|
|
397
|
-
/// Space: O(size)
|
|
398
|
-
/// *Runtime and space assumes that `f` runs in O(1) time and space.
|
|
399
|
-
public func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y] {
|
|
400
|
-
var count = 0;
|
|
401
|
-
let options =
|
|
402
|
-
Prim.Array_tabulate<?Y>(
|
|
403
|
-
array.size(),
|
|
404
|
-
func i {
|
|
405
|
-
let result = f(array[i]);
|
|
406
|
-
switch (result) {
|
|
407
|
-
case (?element) {
|
|
408
|
-
count += 1;
|
|
409
|
-
result
|
|
410
|
-
};
|
|
411
|
-
case null {
|
|
412
|
-
null
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
);
|
|
417
|
-
|
|
418
|
-
var nextSome = 0;
|
|
419
|
-
Prim.Array_tabulate<Y>(
|
|
420
|
-
count,
|
|
421
|
-
func _ {
|
|
422
|
-
while (Option.isNull(options[nextSome])) {
|
|
423
|
-
nextSome += 1;
|
|
424
|
-
};
|
|
425
|
-
nextSome += 1;
|
|
426
|
-
switch(options[nextSome - 1]) {
|
|
427
|
-
case(?element) element;
|
|
428
|
-
case null {
|
|
429
|
-
Prim.trap "Malformed array in mapFilter"
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
)
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
/// Creates a new array by applying `f` to each element in `array`.
|
|
437
|
-
/// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise
|
|
438
|
-
/// returns an `#ok` containing the new array.
|
|
439
|
-
///
|
|
440
|
-
/// ```motoko include=import
|
|
441
|
-
/// let array = [4, 3, 2, 1, 0];
|
|
442
|
-
/// // divide 100 by every element in the array
|
|
443
|
-
/// Array.mapResult<Nat, Nat, Text>(array, func x {
|
|
444
|
-
/// if (x > 0) {
|
|
445
|
-
/// #ok(100 / x)
|
|
446
|
-
/// } else {
|
|
447
|
-
/// #err "Cannot divide by zero"
|
|
448
|
-
/// }
|
|
449
|
-
/// })
|
|
450
|
-
/// ```
|
|
451
|
-
///
|
|
452
|
-
/// Runtime: O(size)
|
|
453
|
-
///
|
|
454
|
-
/// Space: O(size)
|
|
455
|
-
///
|
|
456
|
-
/// *Runtime and space assumes that `f` runs in O(1) time and space.
|
|
457
|
-
public func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E> {
|
|
458
|
-
let size = array.size();
|
|
459
|
-
var target : [var Y] = [var];
|
|
460
|
-
var isInit = false;
|
|
461
|
-
|
|
462
|
-
var error : ?Result.Result<[Y], E> = null;
|
|
463
|
-
let results = Prim.Array_tabulate<?Y>(size, func i {
|
|
464
|
-
switch (f(array[i])) {
|
|
465
|
-
case (#ok element) {
|
|
466
|
-
?element
|
|
467
|
-
};
|
|
468
|
-
case (#err e) {
|
|
469
|
-
switch (error) {
|
|
470
|
-
case null { // only take the first error
|
|
471
|
-
error := ?(#err e);
|
|
472
|
-
};
|
|
473
|
-
case _ { };
|
|
474
|
-
};
|
|
475
|
-
null
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
switch error {
|
|
481
|
-
case null {
|
|
482
|
-
// unpack the option
|
|
483
|
-
#ok(map<?Y, Y>(results, func element {
|
|
484
|
-
switch element {
|
|
485
|
-
case (?element) {
|
|
486
|
-
element
|
|
487
|
-
};
|
|
488
|
-
case null {
|
|
489
|
-
Prim.trap "Malformed array in mapResults"
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
}));
|
|
493
|
-
};
|
|
494
|
-
case (?error) {
|
|
495
|
-
error
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
/// Creates a new array by applying `k` to each element in `array`,
|
|
501
|
-
/// and concatenating the resulting arrays in order. This operation
|
|
502
|
-
/// is similar to what in other functional languages is known as monadic bind.
|
|
503
|
-
///
|
|
504
|
-
/// ```motoko include=import
|
|
505
|
-
/// import Nat "mo:base/Nat";
|
|
506
|
-
///
|
|
507
|
-
/// let array = [1, 2, 3, 4];
|
|
508
|
-
/// Array.chain<Nat, Int>(array, func x = [x, -x])
|
|
509
|
-
///
|
|
510
|
-
/// ```
|
|
511
|
-
/// Runtime: O(size)
|
|
512
|
-
///
|
|
513
|
-
/// Space: O(size)
|
|
514
|
-
/// *Runtime and space assumes that `k` runs in O(1) time and space.
|
|
515
|
-
public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {
|
|
516
|
-
var flatSize = 0;
|
|
517
|
-
let subArrays = Prim.Array_tabulate<[Y]>(array.size(), func i {
|
|
518
|
-
let subArray = k(array[i]);
|
|
519
|
-
flatSize += subArray.size();
|
|
520
|
-
subArray
|
|
521
|
-
});
|
|
522
|
-
// could replace with a call to flatten,
|
|
523
|
-
// but it would require an extra pass (to compute `flatSize`)
|
|
524
|
-
var outer = 0;
|
|
525
|
-
var inner = 0;
|
|
526
|
-
Prim.Array_tabulate<Y>(flatSize, func _ {
|
|
527
|
-
let subArray = subArrays[outer];
|
|
528
|
-
let element = subArray[inner];
|
|
529
|
-
inner += 1;
|
|
530
|
-
if (inner == subArray.size()) {
|
|
531
|
-
inner := 0;
|
|
532
|
-
outer += 1;
|
|
533
|
-
};
|
|
534
|
-
element
|
|
535
|
-
})
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
/// Collapses the elements in `array` into a single value by starting with `base`
|
|
539
|
-
/// and progessively combining elements into `base` with `combine`. Iteration runs
|
|
540
|
-
/// left to right.
|
|
541
|
-
///
|
|
542
|
-
/// ```motoko include=import
|
|
543
|
-
/// import {add} "mo:base/Nat";
|
|
544
|
-
///
|
|
545
|
-
/// let array = [4, 2, 0, 1];
|
|
546
|
-
/// let sum =
|
|
547
|
-
/// Array.foldLeft<Nat, Nat>(
|
|
548
|
-
/// array,
|
|
549
|
-
/// 0, // start the sum at 0
|
|
550
|
-
/// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!
|
|
551
|
-
/// );
|
|
552
|
-
/// ```
|
|
553
|
-
///
|
|
554
|
-
/// Runtime: O(size)
|
|
555
|
-
///
|
|
556
|
-
/// Space: O(1)
|
|
557
|
-
///
|
|
558
|
-
/// *Runtime and space assumes that `combine` runs in O(1) time and space.
|
|
559
|
-
public func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A {
|
|
560
|
-
var accumulation = base;
|
|
561
|
-
|
|
562
|
-
for (element in array.vals()) {
|
|
563
|
-
accumulation := combine(accumulation, element);
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
accumulation
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
// FIXME the type arguments are reverse order from Buffer
|
|
570
|
-
/// Collapses the elements in `array` into a single value by starting with `base`
|
|
571
|
-
/// and progessively combining elements into `base` with `combine`. Iteration runs
|
|
572
|
-
/// right to left.
|
|
573
|
-
///
|
|
574
|
-
/// ```motoko include=import
|
|
575
|
-
/// import {toText} "mo:base/Nat";
|
|
576
|
-
///
|
|
577
|
-
/// let array = [1, 9, 4, 8];
|
|
578
|
-
/// let bookTitle = Array.foldRight<Nat, Text>(array, "", func(x, acc) = toText(x) # acc);
|
|
579
|
-
/// ```
|
|
580
|
-
///
|
|
581
|
-
/// Runtime: O(size)
|
|
582
|
-
///
|
|
583
|
-
/// Space: O(1)
|
|
584
|
-
///
|
|
585
|
-
/// *Runtime and space assumes that `combine` runs in O(1) time and space.
|
|
586
|
-
public func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A {
|
|
587
|
-
var accumulation = base;
|
|
588
|
-
let size = array.size();
|
|
589
|
-
|
|
590
|
-
var i = size;
|
|
591
|
-
while (i > 0) {
|
|
592
|
-
i -= 1;
|
|
593
|
-
accumulation := combine(array[i], accumulation);
|
|
594
|
-
};
|
|
595
|
-
|
|
596
|
-
accumulation;
|
|
597
|
-
};
|
|
598
|
-
|
|
599
|
-
/// Flattens the array of arrays into a single array. Retains the original
|
|
600
|
-
/// ordering of the elements.
|
|
601
|
-
///
|
|
602
|
-
/// ```motoko include=import
|
|
603
|
-
///
|
|
604
|
-
/// let arrays = [[0, 1, 2], [2, 3], [], [4]];
|
|
605
|
-
/// Array.flatten<Nat>(arrays)
|
|
606
|
-
/// ```
|
|
607
|
-
///
|
|
608
|
-
/// Runtime: O(number of elements in array)
|
|
609
|
-
///
|
|
610
|
-
/// Space: O(number of elements in array)
|
|
611
|
-
public func flatten<X>(arrays : [[X]]) : [X] {
|
|
612
|
-
var flatSize = 0;
|
|
613
|
-
for (subArray in arrays.vals()) {
|
|
614
|
-
flatSize += subArray.size()
|
|
615
|
-
};
|
|
616
|
-
|
|
617
|
-
var outer = 0;
|
|
618
|
-
var inner = 0;
|
|
619
|
-
Prim.Array_tabulate<X>(flatSize, func _ {
|
|
620
|
-
while (inner == arrays[outer].size()) {
|
|
621
|
-
inner := 0;
|
|
622
|
-
outer += 1;
|
|
623
|
-
};
|
|
624
|
-
let element = arrays[outer][inner];
|
|
625
|
-
inner += 1;
|
|
626
|
-
element
|
|
627
|
-
})
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
/// Create an array containing a single value.
|
|
631
|
-
///
|
|
632
|
-
/// ```motoko include=import
|
|
633
|
-
/// Array.make(2)
|
|
634
|
-
/// ```
|
|
635
|
-
///
|
|
636
|
-
/// Runtime: O(1)
|
|
637
|
-
///
|
|
638
|
-
/// Space: O(1)
|
|
639
|
-
public func make<X>(element : X) : [X] = [element];
|
|
640
|
-
|
|
641
|
-
/// Returns an Iterator (`Iter`) over the elements of `array`.
|
|
642
|
-
/// Iterator provides a single method `next()`, which returns
|
|
643
|
-
/// elements in order, or `null` when out of elements to iterate over.
|
|
644
|
-
///
|
|
645
|
-
/// NOTE: You can also use `array.vals()` instead of this function. See example
|
|
646
|
-
/// below.
|
|
647
|
-
///
|
|
648
|
-
/// ```motoko include=import
|
|
649
|
-
///
|
|
650
|
-
/// let array = [10, 11, 12];
|
|
651
|
-
///
|
|
652
|
-
/// var sum = 0;
|
|
653
|
-
/// for (element in array.vals()) {
|
|
654
|
-
/// sum += element;
|
|
655
|
-
/// };
|
|
656
|
-
/// sum
|
|
657
|
-
/// ```
|
|
658
|
-
///
|
|
659
|
-
/// Runtime: O(1)
|
|
660
|
-
///
|
|
661
|
-
/// Space: O(1)
|
|
662
|
-
public func vals<X>(array : [X]) : I.Iter<X> = array.vals();
|
|
663
|
-
|
|
664
|
-
/// Returns an Iterator (`Iter`) over the indices of `array`.
|
|
665
|
-
/// Iterator provides a single method `next()`, which returns
|
|
666
|
-
/// indices in order, or `null` when out of index to iterate over.
|
|
667
|
-
///
|
|
668
|
-
/// NOTE: You can also use `array.keys()` instead of this function. See example
|
|
669
|
-
/// below.
|
|
670
|
-
///
|
|
671
|
-
/// ```motoko include=import
|
|
672
|
-
///
|
|
673
|
-
/// let array = [10, 11, 12];
|
|
674
|
-
///
|
|
675
|
-
/// var sum = 0;
|
|
676
|
-
/// for (element in array.keys()) {
|
|
677
|
-
/// sum += element;
|
|
678
|
-
/// };
|
|
679
|
-
/// sum
|
|
680
|
-
/// ```
|
|
681
|
-
///
|
|
682
|
-
/// Runtime: O(1)
|
|
683
|
-
///
|
|
684
|
-
/// Space: O(1)
|
|
685
|
-
public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();
|
|
686
|
-
}
|