Ztep is an Iterator library written in ⚡ZIG ⚡.
It is heavily inspired by the iterators in the Rust standard library std::iter::Iterator.
This also includes optimizations for special iterators, such as for arrays, where it is easy to jump to a specific item (position).
- 0.14.1
- 0.15.1
const std = @import("std");
const iter = @import("ztep");
fn firstChar(in: []const u8) u8 {
return in[0];
}
test "extend" {
var it = iter.extend(std.mem.tokenizeScalar(u8, "x BB ccc", ' '))
.map(u8, firstChar)
.filter(std.ascii.isLower)
.enumerate();
try std.testing.expectEqualDeep(.{ 0, 'x' }, it.next().?);
try std.testing.expectEqualDeep(.{ 1, 'c' }, it.next().?);
try std.testing.expectEqual(null, it.next());
}const std = @import("std");
const iter = @import("ztep");
fn firstChar(in: []const u8) u8 {
return in[0];
}
test "from slice" {
var it = iter.fromSlice(&[_][]const u8{ "x", "BB", "ccc" })
.map(u8, firstChar)
.filter(std.ascii.isLower)
.enumerate();
try std.testing.expectEqualDeep(.{ 0, 'x' }, it.next().?);
try std.testing.expectEqualDeep(.{ 1, 'c' }, it.next().?);
try std.testing.expectEqual(null, it.next());
}const std = @import("std");
const iter = @import("ztep");
test "iterator with error" {
const dir = try std.fs.cwd().openDir(".", .{ .iterate = true });
var walker = try dir.walk(std.testing.allocator);
defer walker.deinit();
// errors are ignored and the next Item is yield
const build = iter.extendWithError(&walker, null).find(struct {
fn find(entry: std.fs.Dir.Walker.Entry) bool {
if (std.mem.eql(u8, "build.zig", entry.basename)) return true else return false;
}
}.find);
try std.testing.expectEqualStrings("build.zig", build.?.basename);
}| Function | Description |
|---|---|
empty |
Creates an iterator that yields nothing. |
extend |
Extend a given Iterator with the additional methods. |
extendWithError |
Extend an Iterator which has a next-method, which returns an error_union (next() anyerror!Item). |
fromFn |
Creates an custom iterator with the initialized (start) value and the provided (next) function. |
fromSlice |
Create an Iterator from a given slice. |
once |
Creates an iterator that yields an element exactly once. |
range |
Create an Iterator from a given start and end value (end is excluded). |
rangeIncl |
Create an Iterator from a given start and end value (end is inclusive). |
repeatN |
Creates a new iterator that N times repeats a given value. |
reverse |
Reverses an iterator’s direction. |
toIterator |
Creates a Wrapper for a given Iterator, where the next-method has a different name. |
| Iterators | Description |
|---|---|
arrayChunks |
Create iterator, which iterate over an chunk of items. |
chain |
Takes two iterators and creates a new iterator over both in sequence. |
count |
Consumes the iterator, counting the number of iterations and returning it. |
enumerate |
Creates an iterator which gives the current iteration count as well as the next value. |
filter |
Creates an iterator which uses a function to determine if an element should be yielded. |
filterMap |
Creates an iterator that both filters and maps in one call. |
find |
Searches for an element of an iterator that satisfies a predicate. |
fold |
Folds every element into an accumulator by applying an operation, returning the final result. |
forEach |
Calls a function fn(Item) on each element of an iterator. |
fuse |
Creates an iterator which ends after the first null. |
inspect |
This iterator do nothing, the purpose is for debugging. |
last |
Calls a function fn(Item) on each element of an iterator. |
map |
Transforms one iterator into another by a given mapping function. |
nth |
Consumes the iterator, returning the nth element. |
peekable |
Creates an iterator which can use the peek methods to look at the next element without consuming it. |
reduce |
Reduces the elements to a single one, by repeatedly applying a reducing function. |
reset |
Reset the Base-Iterator, if the Iterator supports it. |
skip |
Creates an iterator that skips the first n elements. |
stepBy |
Creates an iterator starting at the same point, but stepping by the given amount at each iteration. |
take |
Creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner. |
takeWHile |
Creates an iterator which calls the predicate on each element, and yield elements while it returns true. |
tryCollect |
Collects all the items from an iterator into a given buffer. |
tryCollectInto |
Collects all the items from an iterator into a given collection. |
tryForEach |
An iterator method that applies a fallible function to each item and stopping at the first error. |
zip |
Zips up’ two iterators into a single iterator of pairs. |
Try to rename all files from a given list, with tryForEach.
fn rename(fileName: []const u8) !void {
const newFileName = try std.mem.concat(std.testing.allocator,u8,&[_][]const u8{fileName,".old"});
defer std.testing.allocator.free(newFileName);
try std.fs.cwd().rename(fileName, newFileName);
}
test "tryForEach with error" {
var it = fromSlice(&[_][]const u8{ "a.txt", "not_found", "b.txt" }).tryForEach(rename);
try std.testing.expect(it.hasError());
try std.testing.expectEqual(error.FileNotFound, it.err.?);
try std.testing.expectEqual("not_found", it.err_item.?);
try std.testing.expectEqual("b.txt", it.next().?);
try std.testing.expectEqual(null, it.next());
}You can stop the iterations, with takeWhile and the given predicate.
test "takeWhile" {
// stop the iteration, if the letter is upper case
var it = fromSlice(&[_][]const u8{ "x", "BB", "ccc" })
.map(u8, firstChar)
.takeWhile(std.ascii.isLower);
try std.testing.expectEqual('x', it.next().?);
try std.testing.expectEqual(null, it.next());
}You can iterate not only in one step, but also in chunks: arrayChunks.
test "arrayChunks with filter and map" {
var it = fromSlice(&[_][]const u8{ "x", "BB", "ccc", "d" })
.map(u8, firstChar)
.filter(std.ascii.isLower)
.arrayChunks(2);
try std.testing.expectEqualDeep([_]u8{ 'x', 'c' }, it.next().?);
try std.testing.expectEqual(null, it.next());
// the remainder is 'd'
try std.testing.expectEqual([_]?u8{ 'd', null }, it.iter.remainder);
it.reset();
try std.testing.expectEqual(1, it.count());
}