From dc9ff1428ce6e2d029f0287db223258146d995f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20W=C3=BChr?= Date: Fri, 13 Sep 2024 09:23:41 +0200 Subject: [PATCH] feat(iterator): implement `iterator_window` (closes #1) --- src/brilo.gleam | 30 +++++++++++++++++++++++++++++ test/brilo_test.gleam | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/brilo.gleam b/src/brilo.gleam index 6168981..5aa0616 100644 --- a/src/brilo.gleam +++ b/src/brilo.gleam @@ -21,3 +21,33 @@ pub fn iterator_from_string(string: String) -> Iterator(String) { iterator.unfold(from: string, with: yield) } + +/// Returns an iterator of sliding windows. +/// +/// ## Examples +/// +/// ```gleam +/// iterator.from_list([1,2,3,4,5]) +/// |> iterator_window(3) +/// |> iterator.map(iterator.to_list) +/// |> iterator.to_list +/// // -> [[1, 2, 3], [2, 3, 4], [3, 4, 5]] +/// ``` +/// +/// ```gleam +/// window([1, 2], 4) +/// // -> [] +/// ``` +/// +pub fn iterator_window(i: Iterator(a), by n: Int) -> Iterator(Iterator(a)) { + let yield = fn(x: Iterator(a)) { + let chunk = x |> iterator.take(n) + + case chunk |> iterator.length == n { + True -> Next(chunk, x |> iterator.drop(1)) + False -> Done + } + } + + iterator.unfold(from: i, with: yield) +} diff --git a/test/brilo_test.gleam b/test/brilo_test.gleam index 627252e..4604980 100644 --- a/test/brilo_test.gleam +++ b/test/brilo_test.gleam @@ -17,3 +17,47 @@ pub fn iterator_from_string_test() { |> string.join("") |> should.equal(string) } + +pub fn iterator_window_test() { + [1, 2, 3] + |> iterator.from_list + |> brilo.iterator_window(2) + |> iterator.map(iterator.to_list) + |> iterator.to_list + |> should.equal([[1, 2], [2, 3]]) +} + +pub fn iterator_window_empty_test() { + iterator.empty() + |> brilo.iterator_window(2) + |> iterator.map(iterator.to_list) + |> iterator.to_list + |> should.equal([]) +} + +pub fn iterator_window_one_size_test() { + [1, 2, 3, 4, 5] + |> iterator.from_list + |> brilo.iterator_window(1) + |> iterator.map(iterator.to_list) + |> iterator.to_list + |> should.equal([[1], [2], [3], [4], [5]]) +} + +pub fn iterator_window_full_size_test() { + [1, 2, 3, 4, 5] + |> iterator.from_list + |> brilo.iterator_window(5) + |> iterator.map(iterator.to_list) + |> iterator.to_list + |> should.equal([[1, 2, 3, 4, 5]]) +} + +pub fn iterator_window_over_size_test() { + [1, 2, 3, 4, 5] + |> iterator.from_list + |> brilo.iterator_window(6) + |> iterator.map(iterator.to_list) + |> iterator.to_list + |> should.equal([]) +}