评估两个选项时的条件逻辑

Conditional logic when evaluating two Options

是否有更多 idiomatic/simpler 方法来编写处理两个选项的代码?

object Test extends App {
  val colors = Some(1)
  val sizes = Some(2)

  val ids = colors match {
    case None => {
      sizes match {
        case None => getRegularIds
        case Some(sizes) => getSizeIds
      }
    }
    case Some(colors) => {
      sizes match {
        case None => getColorIds
        case Some(sizes) => getColorIds ++ getSizeIds
      }
    }
  }

  println(ids)

  def getColorIds = Seq(1,2,4)
  def getSizeIds = Seq(4,5,6)
  def getRegularIds = Seq(7,8,9)
}

Scala 如此简洁,以至于我认为可能有一种更简洁的方法来实现相同的结果。谢谢你的时间。

避免嵌套匹配:

val ids2 = (colors, sizes) match {
  case (None, None)       => getRegularIds
  case (Some(_), None)    => getColorIds
  case (None, Some(_))    => getSizeIds
  case (Some(_), Some(_)) => getColorIds ++ getSizeIds
}

您也可以尝试类似的方法:

colors.fold(defaultColors)(_ => getColors) ++ 
  sizes.fold(defaultSizes)(_ => getSizes)

如果您的 SeqList,您也可以使用 Scalaz 的 Semigroup append 来做到这一点,开箱即用:

import scalaz._, Scalaz._

scala> (colors.map(_ => getColorIds) |+| sizes.map(_ => getSizeIds))
         .getOrElse(getRegularIds)
res11: List[Int] = List(1, 2, 4, 4, 5, 6)

以下是其他结果(明确地)显示正在发生的事情:

scala> (Option(List(1, 2, 4)) |+| Option.empty[List[Int]]).getOrElse(getRegularIds)
res14: List[Int] = List(1, 2, 4)

scala> (Option.empty[List[Int]] |+| Option(List(4, 5, 6))).getOrElse(getRegularIds)
res15: List[Int] = List(4, 5, 6)

scala> (Option.empty[List[Int]] |+| Option.empty[List[Int]]).getOrElse(getRegularIds)
res16: List[Int] = List(7, 8, 9)

很遗憾,没有Semigroup[Seq]。有关为什么不这样做的更好解释,请参阅 this answer