Guillaume Massé
Guillaume Massé

Reputation: 8064

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)

Upvotes: 2

Views: 828

Answers (2)

jedesah
jedesah

Reputation: 3033

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

Upvotes: 2

stew
stew

Reputation: 11366

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)

Upvotes: 7

Related Questions