aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanik Vitek <x3665107@gmail.com>2024-03-17 21:57:31 +0200
committerLouis Pilfold <louis@lpil.uk>2024-03-18 15:12:18 +0000
commit2427639f3a5f4495a14d6d766e518589970c632a (patch)
tree009a34ae46dcf341d49c6048448655a709c2ac91 /src
parent0c2faa96418c6a6e4c76a6f87eba265a35e8e3b7 (diff)
downloadgleam_stdlib-2427639f3a5f4495a14d6d766e518589970c632a.tar.gz
gleam_stdlib-2427639f3a5f4495a14d6d766e518589970c632a.zip
Implement `iterator.filter_map`
Diffstat (limited to 'src')
-rw-r--r--src/gleam/iterator.gleam43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam
index 746fbc8..c51e336 100644
--- a/src/gleam/iterator.gleam
+++ b/src/gleam/iterator.gleam
@@ -567,6 +567,49 @@ pub fn filter(
|> Iterator
}
+fn do_filter_map(
+ continuation: fn() -> Action(a),
+ f: fn(a) -> Result(b, c),
+) -> Action(b) {
+ case continuation() {
+ Stop -> Stop
+ Continue(e, next) ->
+ case f(e) {
+ Ok(e) -> Continue(e, fn() { do_filter_map(next, f) })
+ Error(_) -> do_filter_map(next, f)
+ }
+ }
+}
+
+/// Creates an iterator from an existing iterator and a transforming predicate function.
+///
+/// The new iterator will contain elements from the first iterator for which
+/// the given function returns `Ok`, transformed to the value inside the `Ok`.
+///
+/// This function does not evaluate the elements of the iterator, the
+/// computation is performed when the iterator is later run.
+///
+/// ## Examples
+///
+/// ```gleam
+/// import gleam/string
+/// import gleam/int
+/// "a1b2c3d4e5f"
+/// |> string.to_graphemes
+/// |> from_list
+/// |> filter_map(int.parse)
+/// |> to_list
+/// // -> [1, 2, 3, 4, 5]
+/// ```
+///
+pub fn filter_map(
+ iterator: Iterator(a),
+ keeping_with f: fn(a) -> Result(b, c),
+) -> Iterator(b) {
+ fn() { do_filter_map(iterator.continuation, f) }
+ |> Iterator
+}
+
/// Creates an iterator that repeats a given iterator infinitely.
///
/// ## Examples