shayan
shayan

Reputation: 1241

How to rewrite complex conditional as pattern matching?

Is there a way to rewrite this conditional as a pattern matching?

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

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

my only failed attempt was this:

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

Edit: I should explicitly mention that my goal is a pattern matching with only two case clauses as shown above, for it's learning value

Upvotes: 0

Views: 114

Answers (3)

jwvh
jwvh

Reputation: 51271

That logic does make for a rather complicated pattern. I'd be tempted to skip pattern matching.

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

Update incorporating worthy input from @Alexey and @Cyrille Corpet and a suggestion from the IntelliJ IDE. (peer review ;-)

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

Upvotes: 4

prayagupadhyay
prayagupadhyay

Reputation: 31192

You can have multiple pattern matches as below,

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"
}

Upvotes: 1

lambda.xy.x
lambda.xy.x

Reputation: 4998

You can make the pattern match work by having two different matches, but unless you're just calling the same method, there's some unwanted code duplication:

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 _ =>
         ()
  }

Upvotes: 1

Related Questions