diff options
-rw-r--r-- | src/gleam/iterator.gleam | 30 | ||||
-rw-r--r-- | test/gleam/iterator_test.gleam | 7 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index 9146833..010d82a 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -534,3 +534,33 @@ pub fn iterate( ) -> Iterator(element) { unfold(initial, fn(element) { Next(element, f(element)) }) } + +fn do_zip( + left: fn() -> Action(a), + right: fn() -> Action(b), +) -> fn() -> Action(tuple(a, b)) { + fn() { + case left() { + Stop -> Stop + Continue(el_left, next_left) -> + case right() { + Stop -> Stop + Continue(el_right, next_right) -> + Continue(tuple(el_left, el_right), do_zip(next_left, next_right)) + } + } + } +} + +/// Zips two iterators together, emitting values from both +/// until the shorter one runs out. +/// +/// ## Examples +/// +/// > from_list(["a", "b", "c"]) |> zip(range(20, 30)) |> to_list +/// [tuple("a", 20), tuple("b", 21), tuple("c", 22)] +/// +pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(tuple(a, b)) { + do_zip(left.continuation, right.continuation) + |> Iterator +} diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam index 098b1b9..ffe57e4 100644 --- a/test/gleam/iterator_test.gleam +++ b/test/gleam/iterator_test.gleam @@ -264,3 +264,10 @@ pub fn iterate_test() { |> iterator.take(5) |> should.equal([1, 3, 9, 27, 81]) } + +pub fn zip_test() { + iterator.from_list(["a", "b", "c"]) + |> iterator.zip(iterator.range(20, 30)) + |> iterator.to_list + |> should.equal([tuple("a", 20), tuple("b", 21), tuple("c", 22)]) +} |