diff options
author | lrosa007 <lrosa008@gmail.com> | 2020-11-02 18:06:24 -0500 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2020-11-03 14:02:42 +0000 |
commit | 5c4a9750a27876f648b85d9bd7ba4f0e18b66990 (patch) | |
tree | e364bb1ff5e1c661211645f2cc2a3aaa57b1503d | |
parent | e1dce822e1ff14664a30b429b5e2e2cbf3748221 (diff) | |
download | gleam_stdlib-5c4a9750a27876f648b85d9bd7ba4f0e18b66990.tar.gz gleam_stdlib-5c4a9750a27876f648b85d9bd7ba4f0e18b66990.zip |
feat(iterator): add find function
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/gleam/iterator.gleam | 31 | ||||
-rw-r--r-- | test/gleam/iterator_test.gleam | 25 |
3 files changed, 58 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ccebdd..34d64c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,8 @@ - The `dynamic` module gains the `option` function. - The `uri` module gains the `percent_encode` and `percent_decode` functions. - The `os` module gains the `erlang_timestamp` function. -- The `iterator` module gains the `append`, `flatten`, `flat_map` and `step` - functions. +- The `iterator` module gains the `append`, `flatten`, `flat_map`, `step`, + and `find` functions. ## v0.11.0 - 2020-08-22 diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index e75b0a7..81ef2ce 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -463,3 +463,34 @@ pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { |> do_range(start, stop, _) |> Iterator } + +/// Find the first element in a given iterator for which the given function returns +/// True. +/// +/// Returns `Error(Nil)` if the function does not return True for any of the +/// elements. +/// +/// ## Examples +/// +/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) +/// Ok(3) +/// +/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) +/// Error(Nil) +/// +/// > find(from_list([]), fn(x) { True }) +/// Error(Nil) +/// +pub fn find( + in haystack: Iterator(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + case haystack.continuation() { + Continue(element, continuation) -> + case is_desired(element) { + True -> Ok(element) + False -> find(Iterator(continuation), is_desired) + } + Stop -> Error(Nil) + } +} diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam index 426c9f7..0f836c6 100644 --- a/test/gleam/iterator_test.gleam +++ b/test/gleam/iterator_test.gleam @@ -225,3 +225,28 @@ pub fn drop_test() { |> iterator.to_list |> should.equal([5, 6, 7, 8, 9]) } + +type Cat { + Cat(id: Int) +} + +pub fn find_test() { + iterator.range(0, 10) + |> iterator.find(fn(e) { e == 5 }) + |> should.equal(Ok(5)) + + iterator.range(0, 10) + |> iterator.find(fn(e) { e > 10 }) + |> should.equal(Error(Nil)) + + iterator.from_list([]) + |> iterator.find(fn(_x) { True }) + |> should.equal(Error(Nil)) + + iterator.unfold( + Cat(id: 1), + fn(cat: Cat) { iterator.Next(cat, Cat(id: cat.id + 1)) }, + ) + |> iterator.find(fn(cat: Cat) { cat.id == 10 }) + |> should.equal(Ok(Cat(id: 10))) +} |