{"id":16475965,"url":"https://github.com/softprops/zig-iter","last_synced_at":"2025-06-11T13:37:09.658Z","repository":{"id":246110364,"uuid":"819456329","full_name":"softprops/zig-iter","owner":"softprops","description":"iterators for zig","archived":false,"fork":false,"pushed_at":"2024-06-27T04:52:59.000Z","size":45,"stargazers_count":7,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-06T00:09:25.019Z","etag":null,"topics":["iterator","zig","zig-library","zig-package"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/softprops.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-24T14:38:36.000Z","updated_at":"2024-12-08T22:39:32.000Z","dependencies_parsed_at":"2024-06-25T22:44:09.684Z","dependency_job_id":"b0393b55-0464-4611-869b-ed4afdc11009","html_url":"https://github.com/softprops/zig-iter","commit_stats":null,"previous_names":["softprops/zig-iter"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softprops%2Fzig-iter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softprops%2Fzig-iter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softprops%2Fzig-iter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softprops%2Fzig-iter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/softprops","download_url":"https://codeload.github.com/softprops/zig-iter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softprops%2Fzig-iter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259274676,"owners_count":22832547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["iterator","zig","zig-library","zig-package"],"created_at":"2024-10-11T12:41:04.705Z","updated_at":"2025-06-11T13:37:09.639Z","avatar_url":"https://github.com/softprops.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n    zig iter\n\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n    iterators (for zig)\n\u003c/div\u003e\n\n---\n\n[![Main](https://github.com/softprops/zig-iter/actions/workflows/ci.yml/badge.svg)](https://github.com/softprops/zig-iter/actions/workflows/ci.yml) ![License Info](https://img.shields.io/github/license/softprops/zig-iter) ![Release](https://img.shields.io/github/v/release/softprops/zig-iter) [![Zig Support](https://img.shields.io/badge/zig-0.13.0-black?logo=zig)](https://ziglang.org/documentation/0.13.0/)\n\n## what's next()?\n\nIf you are coming to zig from any variety of other languages (we welcome you) you might be asking the questions like: how can I transform this zig collection?, how can I filter out elements?, and other perfectly valid questions based on what you might be used to from where you are coming from. The answer in zig is \"it depends\", but you'll likely be using a for loop and allocating a copy of the collection you have on hand.\n\nLet's use a very simple example: doubling the value of an array of elems that you may do something later with. I'll just print it out for simplicity, but you'll likely be doing something more useful.\n\n```zig\nconst elems = [_]i32{ 1, 2, 3 };\n// 👇 conjure an allocator for the list below\nvar gpa = std.heap.GeneralPurposeAllocator(.{}){};\ndefer _ = gpa.deinit();\nconst allocator = gpa.allocator();\n// 👇 allocate a new list to hold the data of the transformation, DONT FORGET TO DEALLOCATE IT\nvar buf = try std.ArrayList(i32).initCapacity(allocator, elems.len);\ndefer buf.deinit();\nfor (elems) |elem| {\n    buf.appendAssumeCapacity(elem * 2);\n}\n// 👇 capture a ref to the slice of data you want, DONT FORGET TO DEALLOCATE IT\nconst doubled = try buf.toOwnedSlice();\ndefer allocator.free(doubled);\n// 👇 do something with it\nfor (doubled) |elem| {\n    std.debug.print(\"{d}\", .{elem});\n}\n```\n\nThe simple example above quickly becomes much more complicated as additional transformations and filtering is required.\n\nIf you are coming to zig from another language you are probably used to expressing this with something like `elems.map(...)`\n\nWith this library you can _almost_ have that too. Below is an equivalent program but \nsans required additional allocations and zig's required memory deallocation. \n\n```zig\nvar elems = [_]i32 { 1, 2, 3 };\n// 👇 create an interator and apply a transformation\nvar doubled = iter.from(elems)\n    .then().map(i32, struct { fn func(n: i32) i32 { return n * 2; } }.func);\n// 👇 do something with it\nwhile (doubled.next()) |elem| {\n    std.debug.print(\"{d}\", .{elem});\n}\n```\n\nI say _almost_ because \n\n* zig does not support closures, but it does support functions as arguments so we can emulate these to a certain degree with struct fn references\n* some [changes to `usingnamespace`](https://github.com/softprops/zig-iter/issues/1) facilitate the need for an itermediatory method, we use `then()`, to access and chain iterator methods. If zig brings that back in a different form this library's `then()` will no longer been nessessary.\n\n\nThe following functions create iterators\n\n* `from(zigType)` - create an iterator for a native zig type, we're expanding the list of types supported\n* `fromFn(returnType, init, func)` - create an iterator from a generator func\n* `once(value)` - create an iterator that only repeats once\n* `repeat(value)` - create an iterator that repeats a given value indefinitely\n\nThe following methods are available when calling `then()` on iterator types\n\n* `chain(other)` - extends one iterator with another\n* `cycle()` - repeats an iterator indefinitely\n* `filter(func)` - filters an iterator by testing a `func` predicate\n* `fold(returnType, init, func)` - reduces an iterator down to a single value\n* `map(returnType, func)` - transforms an iterator by applying `func`\n* `skip(n)` - skip the first `n` elems of an iterator\n* `take(n)` - take only the first `n` elems of an iterator\n* `zip(iter)` - create an iterator yielding a tuple of iterator values\n\nlikely more to come\n\n\nNote, nothing is allocated behind the scenes. If you do need to take the results and \nstore the result in an allocatoed type simply do what you would do with any iterator: feed \nit values of `next()`\n\n```zig\nvar elems = [_]i32 { 1, 2, 3 };\nvar doubled = iter.from(elems)\n    .then().map(i32, struct { fn func(n: i32) i32 { return n * 2; } }.func);\n\n// now go ahead feed the result into a list\n\n// 👇 conjure an allocator for the list below\nvar gpa = std.heap.GeneralPurposeAllocator(.{}){};\ndefer _ = gpa.deinit();\nconst allocator = gpa.allocator();\n// 👇 allocate a new list to hold the data of the transformation, DONT FORGET TO DEALLOCATE IT\nvar buf = try std.ArrayList(i32).initCapacity(allocator, elems.len);\ndefer buf.deinit();\nwhile (doubled.next()) |elem| {\n    buf.appendAssumeCapacity(elem * 2);\n}\n// 👇 capture a ref to the slice of data you want, DONT FORGET TO DEALLOCATE IT\nconst copied = try buf.toOwnedSlice();\ndefer allocator.free(copied);\n```\n\n## examples\n\nFor more examples see the `examples` directory\n\n## 📼 installing\n\nCreate a new exec project with `zig init`. Copy an example from the examples directory into your into `src/main.zig`\n\nCreate a `build.zig.zon` file to declare a dependency\n\n\u003e .zon short for \"zig object notation\" files are essentially zig structs. `build.zig.zon` is zigs native package manager convention for where to declare dependencies\n\nStarting in zig 0.12.0, you can use and should prefer\n\n```sh\nzig fetch --save https://github.com/softprops/zig-iter/archive/refs/tags/v0.1.0.tar.gz\n```\n\notherwise, to manually add it, do so as follows\n\n```diff\n.{\n    .name = \"my-app\",\n    .version = \"0.1.0\",\n    .dependencies = .{\n+       // 👇 declare dep properties\n+        .iter = .{\n+            // 👇 uri to download\n+            .url = \"https://github.com/softprops/zig-iter/archive/refs/tags/v0.1.0.tar.gz\",\n+            // 👇 hash verification\n+            .hash = \"...\",\n+        },\n    },\n}\n```\n\n\u003e the hash below may vary. you can also depend any tag with `https://github.com/softprops/zig-iter/archive/refs/tags/v{version}.tar.gz` or current main with `https://github.com/softprops/zig-iter/archive/refs/heads/main/main.tar.gz`. to resolve a hash omit it and let zig tell you the expected value.\n\nAdd the following in your `build.zig` file\n\n```diff\nconst std = @import(\"std\");\n\npub fn build(b: *std.Build) void {\n    const target = b.standardTargetOptions(.{});\n\n    const optimize = b.standardOptimizeOption(.{});\n    // 👇 de-reference dep from build.zig.zon`\n+    const iter = b.dependency(\"iter\", .{\n+        .target = target,\n+        .optimize = optimize,\n+    }).module(\"iter\");\n    var exe = b.addExecutable(.{\n        .name = \"your-exe\",\n        .root_source_file = .{ .path = \"src/main.zig\" },\n        .target = target,\n        .optimize = optimize,\n    });\n    // 👇 add the module to executable\n+    exe.root_mode.addImport(\"iter\", iter);\n\n    b.installArtifact(exe);\n}\n```\n\n## 🥹 for budding ziglings\n\nDoes this look interesting but you're new to zig and feel left out? No problem, zig is young so most us of our new are as well. Here are some resources to help get you up to speed on zig\n\n- [the official zig website](https://ziglang.org/)\n- [zig's one-page language documentation](https://ziglang.org/documentation/0.13.0/)\n- [ziglearn](https://ziglearn.org/)\n- [ziglings exercises](https://github.com/ratfactor/ziglings)\n\n\n\\- softprops 2024","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftprops%2Fzig-iter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoftprops%2Fzig-iter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftprops%2Fzig-iter/lists"}