A lightweight, composable iterator library for Zig that brings functional programming patterns to range iteration.
- Lazy Evaluation: Iterators are evaluated on-demand
- Method Chaining: Compose operations with
.map(),.filter(),.find(), and.collect() - Generic Types: Works with any type using Zig's compile-time generics
- Zero Dependencies: Uses only Zig's standard library
const std = @import("std");
const ranges = @import("ranges");
pub fn main() void {
const range = ranges.Range(usize).init(0, 10);
var it = range;
while (it.next()) |value| {
std.debug.print("{} ", .{value});
}
// Output: 0 1 2 3 4 5 6 7 8 9
}const std = @import("std");
const ranges = @import("ranges");
fn isEven(x: usize) bool {
return x % 2 == 0;
}
fn square(x: usize) usize {
return x * x;
}
pub fn main() void {
const range = ranges.Range(usize).init(0, 10);
var it = range
.filter(isEven)
.map(square);
while (it.next()) |value| {
std.debug.print("{} ", .{value});
}
// Output: 0 4 16 36 64
}const std = @import("std");
const ranges = @import("ranges");
fn isEven(x: usize) bool {
return x % 2 == 0;
}
fn square(x: usize) usize {
return x * x;
}
pub fn main() void {
const array = [_]usize{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const arrayRange = ranges.ArrayRange(usize).init(&array);
var it = arrayRange
.filter(isEven)
.map(square);
while (it.next()) |value| {
std.debug.print("{} ", .{value});
}
// Output: 0 4 16 36 64
}const std = @import("std");
const ranges = @import("ranges");
fn isEven(x: usize) bool {
return x % 2 == 0;
}
fn square(x: usize) usize {
return x * x;
}
pub fn main() void {
const range = ranges.Range(usize).init(0, 100);
var it = range
.filter(isEven)
.map(square);
if (it.find(1296)) |found| {
std.debug.print("Found: {}\n", .{found});
} else {
std.debug.print("Not found\n", .{});
}
if (it.find(1)) |found| {
std.debug.print("Found: {}\n", .{found});
} else {
std.debug.print("Not found\n", .{});
}
}const std = @import("std");
const ranges = @import("ranges");
fn isEven(x: usize) bool {
return x % 2 == 0;
}
fn square(x: usize) usize {
return x * x;
}
fn lessThen(x: usize) bool {
return x < 20;
}
pub fn main() !void {
var allocator = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = allocator.deinit();
const gp_allocator = allocator.allocator();
const array = [_]usize{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const range = ranges.ArrayRange(usize).init(&array);
var it = range
.filter(isEven)
.map(square)
.filter(lessThen);
var collected = try it.collect(gp_allocator);
defer collected.deinit(gp_allocator);
std.debug.print("Collected: {any}\n", .{collected.items});
std.debug.print("Type of it: {s}\n", .{@typeName(@TypeOf(it))});
}const std = @import("std");
const ranges = @import("ranges");
const MyStruct = struct {
value: i32,
};
fn squareStruct(s: MyStruct) MyStruct {
return MyStruct{
.value = s.value * s.value,
};
}
fn isEvenStruct(s: MyStruct) bool {
return @mod(s.value, 2) == 0;
}
pub fn main() void {
const array = [_]MyStruct{
.{ .value = 1 },
.{ .value = 2 },
.{ .value = 3 },
.{ .value = 4 },
};
const arrayRange = ranges.ArrayRange(MyStruct).init(&array);
var it = arrayRange
.map(squareStruct)
.filter(isEvenStruct);
while (it.next()) |v| {
std.debug.print("Squared struct value: {}\n", .{v});
}
}const std = @import("std");
const ranges = @import("ranges");
fn toUpperCase(c: u8) u8 {
if (c >= 'a' and c <= 'z') {
return c - 32;
}
return c;
}
pub fn main() !void {
const string = "Hello, Zig Ranges!";
const range = ranges.ArrayRange(u8).init(string);
var it = range
.map(toUpperCase);
while (it.next()) |c| {
std.debug.print("{c}", .{c});
}
std.debug.print("\n", .{});
std.debug.print("{s} \n", .{string});
}
Creates a numeric range iterator.
Methods:
init(start: usize, end: usize)- Create a range from start (inclusive) to end (exclusive)next()- Get the next value, returns?Tmap(comptime F)- Transform each elementfilter(comptime P)- Keep only elements matching a predicatefind(value: T)- Find a specific value, returns?Tcollect(allocator)- Collect all elements into anArrayList(T)
Creates an iterator over array elements.
Methods:
init(arr: []const T)- Create an iterator from a slicenext()- Get the next value, returns?Tmap(comptime F)- Transform each elementfilter(comptime P)- Keep only elements matching a predicatefind(value: T)- Find a specific value, returns?Tcollect(allocator)- Collect all elements into anArrayList(T)
# Build the project
zig build
# Run the example
zig build run
# Run tests
zig test ranges_test.zigThe library includes comprehensive tests. Run them with:
zig test ranges_test.zigTest coverage includes:
- Range iteration with filtering and mapping
- Array range operations
- Finding elements in chains
- Collecting results into
ArrayList - Custom type support
- Zig 0.11.0 or later
This project is open source.
See src/main.zig for a complete working example and src/ranges_test.zig for more usage patterns.