Scala для понимания для orElse вместо flatMap

Я хорошо знаком с for пониманием и flatMap в опциях.

Итак, я знаю, что вы можете сделать что-то вроде

val a: Option[_] = for {
  foo <- Some(x)
  bar <- Some(y)
  baz <- Some(z)
} yield baz

что дает мне Some(z), если ничего в for comprehension не равно None, так как он выполняет flatMap для каждого оператора.

Но на самом деле я ищу что-то наоборот. Я хотел бы перейти к for пониманию, пока все None, как orElse в for понимании.

Например:

val b: Option[_] = for {
    foo <- None
    bar <- Some(x)
    baz <- None
} yield *return the one with some*

Есть ли что-нибудь подобное, или какой лучший подход для этого?

Заранее спасибо!


person pichsenmeister    schedule 15.05.2014    source источник


Ответы (2)


reduce не замкнется, когда найдет Some (т. е. список из тысячи элементов выполнит тысячу сравнений, даже если первым элементом является Some). find(_.isDefined) + flatten остановится и вернет первое найденное Some. Следующее будет делать только 2 сравнения (а не 5).

val xs: List[Option[Int]] = List(None, Some(1), None, Some(2), None, Some(3))
xs.find(_.isDefined).flatten
person wmmeyer    schedule 16.05.2014

Для понимания на самом деле не имеет смысла в вашем сценарии. Вам лучше просто поместить элементы в коллекцию и вытащить не-None.

Может быть, что-то вроде этого?

val xs: List[Option[Int]] = List(None, Some(1), None)
xs.reduce(_ orElse _) // Some(1)

val ys: List[Option[Int]] = List(None, None)
ys.reduce(_ orElse _) // None
person dhg    schedule 15.05.2014
comment
Спасибо! Я не думал об этом, но вполне логично ;) - person pichsenmeister; 16.05.2014