Compare instances of Option[T] avoiding None == None
You could do it with pattern matching (which in this case is probably the clearest way):
(user, server) match {
case (Some(user), Some(server)) if user.id == server.adminId =>
// both ids are matching, handle this case here
case _ =>
// no match, handle this case here
}
You could also try as a one-liner but here I don't advise it as it's pretty obfuscated:
if ( user.flatMap{ user => server.map(_.adminId == user.id) }.getOrElse( false ) ) {
// both ids are matching, handle this case here
}
else {
// no match, handle this case here
}
Finally, if you only have to handle the case where the ids match (and would just do nothing if there is not), using a for comprehension is not too bad of an option (no pun intended):
for ( user <- user; server <- server if user.id == server.adminId ) {
// both ids are matching, handle this case here
}
I got used to the combination of exists
/ contains
for this purpose.
When comparing two options of the same type:
o1.exists(o2.contains)
In your case this can be applied using map
:
user.map(_.id).exists(server.map(_.adminId).contains)
you can use a for comprehension
def isAdmin(server: Option[Server])(user: Option[User]): Boolean = (for {
s <- server
u <- user
} yield (u.id == s.adminId)
).getOrElse(false)
The comprehension results in a Option[Boolean]
from which you get
the value or false
if there's no value (the case where any of the options is None
, as you requested)
Why curried?
I made the method curried, so you can define you function for a specific server, and then reuse that to check many users
def isMyServerAdmin = isAdmin(Some(myServer)) _
isMyServerAdmin(Some(user1)) = true
isMyServerAdmin(Some(user2)) = false
isMyServerAdmin(None) = false