Skip to content

Commit 5c4a975

Browse files
rvcaslpil
authored andcommitted
feat(iterator): add find function
1 parent e1dce82 commit 5c4a975

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
- The `dynamic` module gains the `option` function.
1111
- The `uri` module gains the `percent_encode` and `percent_decode` functions.
1212
- The `os` module gains the `erlang_timestamp` function.
13-
- The `iterator` module gains the `append`, `flatten`, `flat_map` and `step`
14-
functions.
13+
- The `iterator` module gains the `append`, `flatten`, `flat_map`, `step`,
14+
and `find` functions.
1515

1616
## v0.11.0 - 2020-08-22
1717

src/gleam/iterator.gleam

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,34 @@ pub fn range(from start: Int, to stop: Int) -> Iterator(Int) {
463463
|> do_range(start, stop, _)
464464
|> Iterator
465465
}
466+
467+
/// Find the first element in a given iterator for which the given function returns
468+
/// True.
469+
///
470+
/// Returns `Error(Nil)` if the function does not return True for any of the
471+
/// elements.
472+
///
473+
/// ## Examples
474+
///
475+
/// > find(from_list([1, 2, 3]), fn(x) { x > 2 })
476+
/// Ok(3)
477+
///
478+
/// > find(from_list([1, 2, 3]), fn(x) { x > 4 })
479+
/// Error(Nil)
480+
///
481+
/// > find(from_list([]), fn(x) { True })
482+
/// Error(Nil)
483+
///
484+
pub fn find(
485+
in haystack: Iterator(a),
486+
one_that is_desired: fn(a) -> Bool,
487+
) -> Result(a, Nil) {
488+
case haystack.continuation() {
489+
Continue(element, continuation) ->
490+
case is_desired(element) {
491+
True -> Ok(element)
492+
False -> find(Iterator(continuation), is_desired)
493+
}
494+
Stop -> Error(Nil)
495+
}
496+
}

test/gleam/iterator_test.gleam

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,28 @@ pub fn drop_test() {
225225
|> iterator.to_list
226226
|> should.equal([5, 6, 7, 8, 9])
227227
}
228+
229+
type Cat {
230+
Cat(id: Int)
231+
}
232+
233+
pub fn find_test() {
234+
iterator.range(0, 10)
235+
|> iterator.find(fn(e) { e == 5 })
236+
|> should.equal(Ok(5))
237+
238+
iterator.range(0, 10)
239+
|> iterator.find(fn(e) { e > 10 })
240+
|> should.equal(Error(Nil))
241+
242+
iterator.from_list([])
243+
|> iterator.find(fn(_x) { True })
244+
|> should.equal(Error(Nil))
245+
246+
iterator.unfold(
247+
Cat(id: 1),
248+
fn(cat: Cat) { iterator.Next(cat, Cat(id: cat.id + 1)) },
249+
)
250+
|> iterator.find(fn(cat: Cat) { cat.id == 10 })
251+
|> should.equal(Ok(Cat(id: 10)))
252+
}

0 commit comments

Comments
 (0)