如何创建案例类的可选实例?

时间:2017-08-30 12:57:08

标签: scala

假设我有case class A(os: Option[String], ox: Option[Int], oy: Option[Int])并且需要函数(Option[String], Option[Int], Option[Int]) => Option[A]才能返回None如果所有参数都是NoneSome[A],那么:例如

def foo(os: Option[String], ox: Option[Int], oy: Option[Int]): Option[A] = ???

foo(Some("abc"), Some(1), Some(2)) // Some(A(Some("abc"), Some(1), Some(2))
foo(Some("abc"), None, None)       // Some(A(Some("abc"), None, None))
foo(None, None, None)              // None

你会怎么写foo

4 个答案:

答案 0 :(得分:4)

使用匹配:

(os, ox, oy) match {
    case (None, None, None) => None
    case _ => Some(A(os, ox, oy))
}

答案 1 :(得分:2)

也许天真,但有效......

def foo(os: Option[String], ox: Option[Int], oy: Option[Int]): Option[A] = 
  (os, ox, oy) match {
    case (None, None, None) => None
    case (x, y, z) => Some(A(x, y, z))
  }

答案 2 :(得分:1)

变体:

def foo(os: Option[String], ox: Option[Int], oy: Option[Int]): Option[A] =
  if (Seq(os, ox, oy).forall(_.isEmpty)) None
  else Some(A(os, ox, oy))

另一种变化:

def foo(os: Option[String], ox: Option[Int], oy: Option[Int]): Option[A] = 
     Seq(os, ox, oy).find(_.isDefined).fold[Option[A]](None)(_ => Some(A(os,ox,oy)))

答案 3 :(得分:-2)

使用flatMap

class A(o1: Option[String], o2: Option[Int], o3: Option[Int])

  def foo(o1: Option[String], o2: Option[Int], o3: Option[Int]): Option[A] = {
    o1.flatMap(x => o2.flatMap(b => o3.flatMap(c => Some(new A(Some(x), o2, o3)))))
  }

使用for comphreension

 class A(o1: Option[String], o2: Option[Int], o3: Option[Int])

  def foo(o1: Option[String], o2: Option[Int], o3: Option[Int]): Option[A] = {
   (for {
     a1 <- o1
     a2 <- o2
     a3 <- o3
   } yield Some(new A(Some(a1), o2, o3))).flatten
  }

已建议使用模式匹配,因此我不会在此处发布