如何将复杂条件重写为模式匹配?

时间:2017-06-02 20:16:22

标签: scala pattern-matching

有没有办法将此条件重写为模式匹配?

val oldEmail : Option[String]
val newEmail : Option[String]

if (newEmail.isDefined && (oldEmail.isEmpty || newEmail.get != oldEmail.get))
   sendActivationEmail(newEmail.get)
else
   ()

我唯一失败的尝试是:

(newEmail, oldEmail) match {
    case (Some(_), None) | (Some(ne), Some(oe)) if ne != oe =>
        sendActivationEmail(newEmail.get)
    case _ => ()
}

编辑:我应该明确提到我的目标是只与上面显示的两个案例条款匹配的模式,因为它的学习价值

3 个答案:

答案 0 :(得分:4)

这种逻辑确实造成了一种相当复杂的模式。我很想跳过模式匹配。

newEmail.collect{
  case ne if oldEmail.fold(true)(_ != ne) => sendActivationEmail(ne)
}

更新包含来自@Alexey和@Cyrille Corpet的有价值的输入以及IntelliJ IDE的建议。 (同行评审; - )

newEmail.foreach(ne => if (!oldEmail.contains(ne)) sendActivationEmail(ne))

答案 1 :(得分:1)

您可以进行多种模式匹配,如下所示

test("given empty old email sends email to new email") {
  val oldEmailOpt : Option[String] = None
  val newEmailOpt : Option[String] = Some("this-is-my-beatifool email")

  val result = newEmailOpt match {
    case Some(newEmail) => oldEmailOpt match {
      case Some(oldEmail) if !newEmail.equals(oldEmail) => "send email to new email"
      case None => "send email to new email"
    }
    case None => "sending email to new email"
  }

  result shouldBe "send email to new email"
}

答案 2 :(得分:1)

您可以通过两个不同的匹配来使模式匹配工作,但除非您只是调用相同的方法,否则会出现一些不需要的代码重复:

def f2(newEmail:Option[String], oldEmail:Option[String]) =
  (newEmail, oldEmail) match {
    case (Some(ne), None) =>
        sendActivationEmail(ne)
    case (Some(ne), Some(oe)) if ne != oe =>
        sendActivationEmail(ne)
    case _ =>
         ()
  }