diff options
-rw-r--r-- | src/gleam/iterator.gleam | 30 | ||||
-rw-r--r-- | test/gleam/iterator_test.gleam | 12 |
2 files changed, 42 insertions, 0 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index daadea0..10f51a8 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -997,3 +997,33 @@ pub fn once(f: fn() -> element) -> Iterator(element) { pub fn single(elem: element) -> Iterator(element) { once(fn() { elem }) } + +fn do_interleave( + current: fn() -> Action(element), + next: fn() -> Action(element), +) -> Action(element) { + case current() { + Stop -> next() + Continue(e, next_other) -> + Continue(e, fn() { do_interleave(next, next_other) }) + } +} + +/// Creates an iterator that alternates between the two given iterators +/// until both have run out. +/// +/// ## Examples +/// +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list +/// [1, 11, 2, 12, 3, 13, 4, 14] +/// +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list +/// [1, 100, 2, 3, 4] +/// +pub fn interleave( + left: Iterator(element), + with right: Iterator(element), +) -> Iterator(element) { + fn() { do_interleave(left.continuation, right.continuation) } + |> Iterator +} diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam index 338db81..8d426e9 100644 --- a/test/gleam/iterator_test.gleam +++ b/test/gleam/iterator_test.gleam @@ -411,3 +411,15 @@ pub fn single_test() { |> iterator.to_list |> should.equal([1]) } + +pub fn interleave_test() { + iterator.from_list([1, 2, 3, 4]) + |> iterator.interleave(with: iterator.from_list([11, 12, 13, 14])) + |> iterator.to_list + |> should.equal([1, 11, 2, 12, 3, 13, 4, 14]) + + iterator.from_list([1, 2, 3, 4]) + |> iterator.interleave(with: iterator.from_list([100])) + |> iterator.to_list + |> should.equal([1, 100, 2, 3, 4]) +} |