Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare instances of Option[T] avoiding None == None

Tags:

scala

Yesterday I was suddenly enlighted and understood how and why people use 'map' method with Option to compare values. Yes, I'm a bit slow, sorry :)

I revised these very nice links and came to the question I would like to ask.

http://twitter.github.com/effectivescala

http://blog.tmorris.net/posts/scalaoption-cheat-sheet

In my Lift webapp I have some Option[User] and Option[Server] variables. I'm trying to find out if this User is admin of this Server by the following check

if(user.map(_.id) == server.map(_.adminId))

But I noticed that in case of 'user' is None and 'server' is also None this check succeeds which is not good for me (if any of them is None I'd like this check to fail). I could add user.isDefined condition but I feel there is more correct way to do it. Could you tell how to accomplish it in Scala way?

like image 265
Soteric Avatar asked Jan 28 '13 18:01

Soteric


2 Answers

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
}
like image 131
Régis Jean-Gilles Avatar answered Nov 01 '22 20:11

Régis Jean-Gilles


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)
like image 34
Suma Avatar answered Nov 01 '22 19:11

Suma