假设我有一个方法foo
:
def foo(i:Int):Option[Int] = ??? // some code
现在,我想对Seq
Int
进行操作,如下所示:
Seq(1, 2).map{
case int => foo(int)
}.collect{
case Some(int) => int
}
结合这种方法的一种方法是:
Seq(1, 2).collect{
case int if foo(int).isDefined => foo(int)
}
有什么方法可以避免两次致电foo
吗?
所以基本上我希望在foo(int)
的LHS上定义=>
作为准备在RHS上使用的变量,而不是必须再次计算它。
答案 0 :(得分:1)
foo(int)
仅存在于if
的范围内,所以没有。我不认为这是可能的。一般情况下,我可能会使用类似于您使用map
和collect
的第一个代码块的内容,因为foo
仅在该上下文中调用一次。
在某些情况下,也可以完全重新定义问题。例如,可以使用flatMap
:
def foo(i: Int): Option[Int] = Option(i).filter(_ > 1)
scala> Seq(1, 2).flatMap(foo)
res0: Seq[Int] = List(2)
答案 1 :(得分:1)
对于您提供的案例,如果foo
是部分函数,则可以执行
Seq(1, 2).collect{foo}
方便的是,我们可以使用foo
foo
变成这样的部分函数(仅在Some(...)
返回Function.unlift
时定义)
让我们定义合适的foo
def foo(i:Int) = i match { case 1 => Some(42) ; case _ => None }
并测试它
Seq(1, 2).collect{
case int if foo(int).isDefined => foo(int)
}
// Seq[Option[Int]] = List(Some(42))
现在" unlift"它是一个部分功能
val partialFoo = Function.unlift(foo)
并测试:
Seq(1, 2).collect{partialFoo}
// Seq[Int] = List(42)
所以你没有得到包含在Some(...)
中的价值,但我认为无论如何你都会打开它,因为原始代码会包含Some(...)