说我有这个:
def expensiveTest(t: String): Option[Int] = {...}
// myList: List[String]
myList.collectFirst {
case x if expensiveTest(x).isDefined => expensiveTest(x).get
}
这样的东西有效,但是......我必须两次调用expensiveTest()。有没有办法将看守的调用结果保存到=>右侧的昂贵测试?
答案 0 :(得分:3)
将列表切换为惰性流并使用map/head
可能是另一种选择:
myList.toStream.flatMap { case x => expensiveTest(x) }.head
答案 1 :(得分:1)
是的,还有办法。我们可以使用提取器模式
object ExpensiveTest {
unapply(x: String): Option[String] = if (x.isEmpty) None else Some(x) // Some logic
}
myList.collectFirst {
case ExpensiveTest(nonEmptyString) => nonEmptyString
}
答案 2 :(得分:0)
Xavier的解决方案很好但如果myList为空则会失败。另一种替代方法是使用尾递归:
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)