coder25
coder25

Reputation: 2393

Possible ways to write for comprehension to handle multiple options

I have a function defined which return Option .

The below code works fine

 def func :Option[Result]= {
  (for {
    src <- ele2
    id <- ele
  } yield {
    src match {
      case "test2" => Option(id.value).map(_.take(3))
          .filterNot(_ == "de").map(id => Result(id))
      case _ => None
    }
  }).getOrElse(None)
}

If I remove getOrElse(None) I get compile error that Iterable[Option[Result]] does not match expected type Option[Result]

I want to get rid of getOrElse(None).Is there a possible way to write the code

Upvotes: 1

Views: 261

Answers (2)

michalkowol
michalkowol

Reputation: 36

For comprehensions in Scala is just syntactic sugar for flatMap and map. In some situations it is better to rewrite your for comprehensions using flatMap and map.

def func: Option[Result] = {
  ele2.flatMap { src =>
    ele.flatMap { id =>
      src match {
        case "test2" => Option(id.value).map(_.take(3))
          .filterNot(_ == "de").map(id => Result(id))
        case _ => None
      }
    }
  }
}

The other option is just extract logic from yield to function

def func: Option[Result] = {
  def innerLogic(src: String, id: Demo): Option[Result] = {
    src match {
      case "test2" => Option(id.value).map(_.take(3))
        .filterNot(_ == "de").map(id => Result(id))
      case _ => None
    }
  }

  for {
    src <- ele2
    id <- ele
    res <- innerLogic(src, id)
  } yield {
    res
  }
}

Upvotes: 0

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149518

How about:

val res: Option[Result] = for {
  src <- ele2
  if src == "test2"
  id <- ele
} yield Result(id.value)

Upvotes: 3

Related Questions