From: Brendan Hansen Date: Wed, 7 Jun 2023 15:38:23 +0000 (-0500) Subject: added `iter.flatten` X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c7e8967228e0e4414a143141f0ebbb833e6c281b;p=onyx.git added `iter.flatten` --- diff --git a/CHANGELOG b/CHANGELOG index 8643caf1..7fe412d0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ Additions: - `[captures] { body }` for blocks. - `[captures] ( expr )` for expressions. - `Optional.with` for running a block of code with the value in an Optional, if one is present. +- `iter.flatten` Removals: - Remove old syntax for quoted blocks, `#quote` and `#()`. diff --git a/core/container/iter.onyx b/core/container/iter.onyx index d7a78478..b39b5e9a 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -25,6 +25,7 @@ use core.intrinsics.types {type_is_struct} skip :: skip; skip_while :: skip_while; + flatten :: flatten; enumerate :: enumerate; fold :: fold; @@ -422,6 +423,35 @@ zip :: (left_iterator: Iterator($T), right_iterator: Iterator($R)) -> Iterator(P } +#doc """ + Filters and maps at the same time. + + If the provided function returns a None variant of Optional, + then the entry is discarded. + + If the provided function returns `Some(x)`, then `x` is yielded. +""" +flatten :: (i: Iterator($T), f: (T) -> ? $R) -> Iterator(R) { + return generator( + &.{ i = i, f = f }, + + fi => { + while true { + v, cont := next(fi.i); + if !cont do break; + + v2 := fi.f(v); + if v2 { + return v2->unwrap(), true; + } + } + return .{}, false; + }, + + fi => { close(fi.i); } + ); +} + #doc """ Combines iterators by first yielding all values from