A library with utility functions and data types for creating efficient iterators in Motoko. This library is inspired by the itertools libraries in both python and rust.
For a complete list of functions and data types, see the Itertools documentation
Demo: https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=1138180896
To get started, you'll need to import the Iter
module from both the base library and this one.
import Iter "mo:base/Iter";
import Itertools "mo:itertools/Iter";
Converting data types to iterators is the next step.
-
Array
[1, 2, 3, 4, 5].vals()
Iter.fromArray([1, 2, 3, 4, 5])
-
List
Iter.fromList(list)
-
Text
"Hello, world!".chars()
Text.split("a,b,c", #char ',')
-
Buffer
Buffer.toArray(buffer).vals()
For conversion of other data types to iterators, you can look in the base library for the specific data type's documentation.
Here are some examples of using the functions in this library to create simple and efficient iterators for solving different problems:
- An example, using
range
andsum
to find the sum of values from 1 to 25:
let range = Itertools.range(1, 25 + 1);
let sum = Itertools.sum(range);
assert sum == ?325;
- Splitting an array into chunks of size 3:
let vals = [1, 2, 3, 4, 5, 6].vals();
let chunks = Itertools.chunks(vals, 3);
assert Iter.toArray(chunks) == [[1, 2, 3], [4, 5, 6]];
- Finding the difference between consecutive elements in an array:
let vals = [5, 3, 3, 7, 8, 10].vals();
let tuples = Itertools.slidingTuples(vals);
// Iter.toArray(tuples) == [(5, 3), (3, 3), (3, 7), (7, 8), (8, 10)]
let diff = func (x : (Int, Int)) : Int { x.1 - x.0 };
let iter = Iter.map(tuples, diff);
assert Iter.toArray(iter) == [-2, 0, 4, 1, 2];
- Reversing a list of integers and chunking them
import Itertools "mo:itertools/Iter";
import RevIter "mo:itertools/RevIter";
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// create a Reversible Iterator from an array
let iter = RevIter.fromArray(arr);
// reverse iterator
let rev_iter = iter.rev();
// Reversible Iterator gets typecasted to an Iter type
let chunks = Itertools.chunks(rev_iter, 3);
assert Iter.toArray(chunks) == [
[10, 9, 8], [7, 6, 5], [4, 3, 2], [1]
];
Any contributions to this library are welcome. Ways you can contribute:
- Fix a bug or typo
- Improve the documentation
- Make a function more efficient
- Suggest a new function to add to the library
- Download and Install vessel
- Run
make test
Iter to PeekableIter | fromIter |
Main Methods | new, map, range, intRange, |
Collection to RevIter | fromArray, fromVarArray, fromDeque |
RevIter to Collection | toArray, toVarArray, toDeque |
Augmenting | accumulate, add, countAll, enumerate, flatten, flattenArray, intersperse, mapEntries, mapWhile,runLength,pad, padWithFn, partitionInPlace, prepend, successor, uniqueCheck |
Combining | interleave, interleaveLongest, merge, kmerge, zip, zip3, zipLongest |
Combinatorics | combinations, cartesianProduct, permutations |
Look ahead | peekable, spy |
Grouping | chunks, chunksExact, groupBy, splitAt, tuples, triples, unzip, |
Repeating | cycle, repeat, |
Selecting | find, findIndex, findIndices, mapFilter, max, min, minmax, nth, nthOrDefault, skip, skipWhile, stepBy, take, takeWhile, unique |
Sliding Window | slidingTuples, slidingTriples |
Summarising | all, any, count, equal, fold, mapReduce, notEqual, isSorted, isSortedDesc, isPartitioned, isUnique, product, reduce, sum, |
Collection to Iter | fromArraySlice, fromTrieSet |
Iter to Collection | toBuffer, toDeque, toText, toTrieSet |
Others | inspect, range, intRange, ref, sort, tee, |