Reputation: 1241
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
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
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
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