Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you write foldWhile with the standard library?

is it possible to write the folowing code with the scala standard library ?

def foldWhile[A,B](s: Stream[A])(z: B)(w: B ⇒ Boolean)(op: (B, A) ⇒ B): B = {
    if(s.isEmpty) z
    else {
        if(w(z)) foldWhile(s.tail)(op(z, s.head))(w)(op)
        else z
    }
}

foldWhile(Stream(1,2,3,4))(0)(_ <= 3)((acc, v) => acc + v)
like image 826
Guillaume Massé Avatar asked Feb 14 '26 23:02

Guillaume Massé


2 Answers

Though I personally think it is grimey, you can have a return in the middle of a fold:

def foldWhile[A,B](s: TraversableOnce[A])(z: B)(w: B ⇒ Boolean)(op: (B, A) ⇒ B): B = 
  s.foldLeft[B](z)((b,a) ⇒ if(w(b)) op(b,a) else return b)
like image 164
stew Avatar answered Feb 16 '26 11:02

stew


Stream(1,2,3,4).scanLeft(0){_ + _}.takeWhile(_ <= 3).last

UPDATE 1

So, funny story, I'm friends with Guillaume (he asked the question before I got to the office) and above is actually what he wants, the bug is in the code in the question.

But if you want the exact logic of the question, you could write something like this:

val results = Stream(1,2,3,4).scanLeft(0){_ + _}
val index = results.indexWhere(_ > 3)
results(index)

I haven't found a one liner for it yet though.

UPDATE 2

Stream(1,2,3,4).scanLeft(0){_ + _}.dropWhile(_ <= 3).head
like image 29
jedesah Avatar answered Feb 16 '26 13:02

jedesah