Scala模式匹配聚合多个匹配

时间:2014-12-02 08:44:29

标签: scala

如果我有案例类

case class Test(a: Option[Boolean], b: Option[Boolean], c: Option[Boolean], d: Option[Boolean])

我必须找到一个Boolean结果,类Test的所有参数都是。{例如:

Test(None, None, Some(true), Some(false))

应该会产生false

Test(Some(true), None, Some(true), None)

会产生true

我正在考虑使用模式匹配,但是我必须匹配每个可能的场景并且这很多,如果添加更多参数,代码会呈指数级增长。

但我可以做点什么吗

Test(Some(true), None, Some(true), None) match {
    case (_, _, _, Some(b)) => b
    case (_, _, Some(b), _) => b
    case (_, Some(b), _, _) => b
    case (Some(b), _, _, _) => b
}

并将所有b汇总到一个Boolean个结果中?

2 个答案:

答案 0 :(得分:5)

对于所有已定义参数的连接,请考虑这个,

case class Test(a: Option[Boolean], 
                b: Option[Boolean], 
                c: Option[Boolean], 
                d: Option[Boolean]) {

  def and() = this.productIterator
                  .collect { case Some(b: Boolean) => b }.reduce(_&&_)
}

案例类扩展trait Product,为实例配备处理参数的方法。

因此,

Test(None, None, Some(true), Some(false)).and()
res: false

Test(Some(true), None, Some(true), None).and()
res: true

此处,我们迭代Any提供的productIterator类型的所有值,并收集已定义并可转换为Boolean的值;对reduce的调用将传递所有收集的Boolean

<强>更新

定义明确的版本,

case class Test(a: Option[Boolean], 
                b: Option[Boolean], 
                c: Option[Boolean], 
                d: Option[Boolean]) {

  def and() = {
    val b = this.productIterator.collect { case Some(b: Boolean) => b }
    if (b.isEmpty) false else b.reduce(_&&_)
  }
}

答案 1 :(得分:1)

如果您只关心合并结果,只需使用列表 展平,然后 forall

 scala> List(Some(true), None, Some(false), Some(true)).flatten.forall(identity)
 res2: Boolean = false

由于尚未定义如果只有 s会发生什么情况,你必须通过明确检查并在那种情况下想要发生的事情来描述案例。