Skip to content

Commit

Permalink
feat: implement dropWhile function
Browse files Browse the repository at this point in the history
Drops elements from the source as long as the predicate is satisfied.
Note the if predicate fails then subsequent elements are no longer
dropped even if they could still satisfy it. Examples:

  Source.empty[Int].dropWhile(_ > 3).toList          // List()
  Source.fromValues(1, 2, 3).dropWhile(_ < 3).toList // List(3)
  Source.fromValues(1, 2, 1).dropWhile(_ < 2).toList // List(2, 1)
  • Loading branch information
geminicaprograms committed Oct 16, 2023
1 parent ea8a9c3 commit 77a9a8c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
19 changes: 19 additions & 0 deletions core/src/main/scala/ox/channels/SourceOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,25 @@ trait SourceOps[+T] { this: Source[T] =>
*/
def drop(n: Int)(using Ox, StageCapacity): Source[T] = transform(_.drop(n))

/** Drops elements from the source as long as predicate `f` is satisfied (returns `true`). Note that once the predicate `f` is not
* satisfied (returns `false`) no elements are dropped from the source even if they could still satisfy it.
*
* @param f
* A predicate function.
* @example
* {{{
* import ox.*
* import ox.channels.Source
*
* scoped {
* Source.empty[Int].dropWhile(_ > 3).toList // List()
* Source.fromValues(1, 2, 3).dropWhile(_ < 3).toList // List(3)
* Source.fromValues(1, 2, 1).dropWhile(_ < 2).toList // List(2, 1)
* }
* }}}
*/
def dropWhile(f: T => Boolean)(using Ox, StageCapacity): Source[T] = transform(_.dropWhile(f))

def filter(f: T => Boolean)(using Ox, StageCapacity): Source[T] = transform(_.filter(f))

def transform[U](f: Iterator[T] => Iterator[U])(using Ox, StageCapacity): Source[U] =
Expand Down
34 changes: 34 additions & 0 deletions core/src/test/scala/ox/channels/SourceOpsDropWhileTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ox.channels

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import ox.*

class SourceOpsDropWhileTest extends AnyFlatSpec with Matchers {
behavior of "Source.drop"

it should "not drop from the empty source" in scoped {
val s = Source.empty[Int]
s.dropWhile(_ > 0).toList shouldBe List.empty
}

it should "drop elements from the source while predicate is true" in scoped {
val s = Source.fromValues(1, 2, 3)
s.dropWhile(_ < 3).toList shouldBe List(3)
}

it should "drop elements from the source until predicate is true and then emit subsequent ones" in scoped {
val s = Source.fromValues(1, 2, 3, 2)
s.dropWhile(_ < 3).toList shouldBe List(3, 2)
}

it should "not drop elements from the source if predicate is false" in scoped {
val s = Source.fromValues(1, 2, 3)
s.dropWhile(_ > 3).toList shouldBe List(1, 2, 3)
}

it should "not drop elements from the source when predicate is false for first or more elements" in scoped {
val s = Source.fromValues(1, 4, 5)
s.dropWhile(_ > 3).toList shouldBe List(1, 4, 5)
}
}

0 comments on commit 77a9a8c

Please sign in to comment.