迭代Option实例,直到找到第一个非空

时间:2014-09-26 10:34:22

标签: scala functional-programming

我有许多返回Option值的函数,比如

case class A()
case class B() 
case class C()

def optionA(): Option[A] = None
def optionB(): Option[B] = Some(B())
def optionC(): Option[C] = Some(C())

我想要做的是,我想按顺序运行这些函数,但只有在其中一个函数返回带有值(Option)的Some之后。然后我希望返回该值,而不运行其余的函数。

这是我目前的实施

val res:Option[Any] = Stream(
  () => optionA(),
  () => optionB(),
  () => optionC()
) .map(f => f())
  .filter(opt => opt.isDefined)
  .head

对于上面的函数实现,这适用于optionAoptionB,给我一个Some(B()),它永远不会运行optionC,这就是我想要的。

但我想知道是否有更好/更简单/替代的实施方案。

val findFirst = optionA compose optionB compose optionC

之类的东西

2 个答案:

答案 0 :(得分:6)

optionA().orElse(optionB()).orElse(optionC())
如果定义orElse

this将不会评估其参数。

或者,如果您已经在集合/流中有选项,那么您可以

options.find(_.isDefined).flatten

答案 1 :(得分:1)

假设你现在拥有Option的集合,那么你可以这样做:

coll.foldLeft[Option[Int]](None)(_ orElse _)

这将返回集合中的第一个非None

请注意,我明确提到了集合的类型,因为scala无法推断orElse没有它应该做什么......(默认情况下None类型为Option[Any]

如果您有一个巨大的选项列表,那么编写

可能会有所帮助
coll.view.foldLeft[Option[Int]](None)(_ orElse _)