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

时间:2016-07-30 20:05:47

标签: scala options

是否有更惯用/更简单的方法来编写处理两个选项的代码?

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如此简洁,以至于我认为可能有更简洁的方法来实现相同的结果。谢谢你的时间。

2 个答案:

答案 0 :(得分:2)

避免嵌套匹配:

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)

答案 1 :(得分:0)

如果您的SeqList s,您也可以使用Scalaz的Semigroup追加,即开即用:

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以获得更好的解释。