Reputation: 11542
Say I have this:
def expensiveTest(t: String): Option[Int] = {...}
// myList: List[String]
myList.collectFirst {
case x if expensiveTest(x).isDefined => expensiveTest(x).get
}
Something like this works, but... I have to call expensiveTest() twice. Is there a way to save the result of the guard's call to expensiveTest to use on the right side of the =>?
Upvotes: 3
Views: 128
Reputation: 2928
Xavier's solution is good but it will fail if myList is empty. Another alternative approach is simply using tail recursion:
import scala.annotation.tailrec
val l = List(1,2,3,4,5)
def expensiveTest(t: Int): Option[Int] = if(t % 2 == 0) Some(t) else None
@tailrec
def f(l: List[Int]): Option[Int] = {
l match {
case Nil => None
case h :: t => expensiveTest(h) match {
case None => f(t)
case x => x
}
}
}
scala> f(l)
res0: Option[Int] = Some(2)
Upvotes: 0
Reputation: 61774
Switching the List to a lazy Stream and using a map/head
could be an alternative:
myList.toStream.flatMap { case x => expensiveTest(x) }.head
Upvotes: 3
Reputation: 14825
Yes, There is a way to do. We can use extractor pattern
object ExpensiveTest {
unapply(x: String): Option[String] = if (x.isEmpty) None else Some(x) // Some logic
}
myList.collectFirst {
case ExpensiveTest(nonEmptyString) => nonEmptyString
}
Upvotes: 1