Only evaluate position when reaching cumulative sum threshold in LazyList

Viewed 44

I would like to find a position of reaching a fixed threshold (e.g. 10) in a lazy list of 2's e.g.:

LazyList.
    continually(2).
    zipWithIndex.
    scanLeft((0,0)){case (acc, el) => (acc._1 + el._1, el._2)}.
    takeWhile(_._1 <= 10)

res72: LazyList[(Int, Int)] = LazyList(
  (0, 0),
  (2, 0),
  (4, 1),
  (6, 2),
  (8, 3),
  (10, 4)
)

Is it possible to do the same without collecting all the intermediate results, in functional way, only returning final position when the cumulative sum is reached, with foldLeft e.g. or similar?

1 Answers

Yes, you can use collectFirst, also I would move the zipWithIndex after the scanLeft

LazyList
  .continually(2)
  .scanLeft(0)((acc, x) => acc + x)
  .zipWithIndex
  .collectFirst {
    case (x, idx) if (x >= 10) => idx
  }

That returns an Option[Int] because the collect may never match, but you know it will in this case so you can just .get or .getOrElse(new IllegalStateException("This should have never happened"))

Related