假设我有一个列表xs: List[X]
,其功能为f(x:X):Y
和g(y):Boolean
。现在我需要找到第一个y = f(x)
以便g(y) == true
。
def findY(xs: List[X], f: X => Y, g: Y => Boolean): Option[Y] = ???
我可以使用xs.map(f).find(g)
执行此操作,但我不想遍历整个列表xs
。我也不想使用流。您如何建议实施findY
?
答案 0 :(得分:8)
使用视图
xs.view.map(f).find(g)
答案 1 :(得分:1)
而不是
xs.map(f).find(g)
只需转过来
xs.find(x => g(f(x)))
在这两种情况下都会返回Option[X]
。
如果你想要Option[Y]
,递归方法可以完成这项任务:
@tailrec
def findFirst[X, Y](xs: List[X], f: X => Y, g: Y => Boolean): Option[Y] = {
xs match {
case Nil =>
None
case h :: t =>
val y = f(h)
if (g(y)) {
Some(y)
} else {
findFirst(t, f, g)
}
}
}
答案 2 :(得分:0)
另一种可能性是使用collectFirst
,它也会返回Option
。
xs.collectFirst{case x if g(f(x)) => f(x)}
唯一的缺点是如果找到匹配的东西,你会评估f(x)
两次。
我不确定是否可以将结果f(x)
绑定到某个变量。