14

昨天我突然被启发并理解了人们如何以及为什么使用带有 Option 的“map”方法来比较值。是的,我有点慢,对不起:)

我修改了这些非常好的链接并提出了我想问的问题。

http://twitter.github.com/effectivescala

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

在我的 Lift webapp 中,我有一些 Option[User] 和 Option[Server] 变量。我正在尝试通过以下检查确定此用户是否是此服务器的管理员

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

但我注意到,如果“用户”为“无”且“服务器”也为“无”,则此检查成功,这对我不利(如果其中任何一个为“无”,我希望此检查失败)。我可以添加 user.isDefined 条件,但我觉得有更正确的方法可以做到这一点。你能告诉如何用 Scala 方式完成它吗?

4

4 回答 4

26

您可以使用模式匹配来做到这一点(在这种情况下,这可能是最清晰的方法):

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

您也可以尝试单线,但在这里我不建议这样做,因为它非常模糊:

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
}

最后,如果您只需要处理 id 匹配的情况(如果不匹配则什么都不做),使用 for 理解并不是一个太糟糕的选项(没有双关语):

for ( user <- user; server <- server if user.id == server.adminId ) {
  // both ids are matching, handle this case here
}
于 2013-01-28T19:05:31.117 回答
16

为此,我习惯了exists/的组合。contains

比较同一类型的两个选项时:

o1.exists(o2.contains)

在您的情况下,可以使用以下方法应用map

user.map(_.id).exists(server.map(_.adminId).contains)
于 2017-04-08T19:51:00.210 回答
3

你可以使用 for 理解

def isAdmin(server: Option[Server])(user: Option[User]): Boolean = (for {
    s <- server
    u <- user
  } yield (u.id == s.adminId)
).getOrElse(false)

理解会导致Option[Boolean]您从中get获得价值,或者false如果没有价值(None根据您的要求,任何选项都是 的情况)

为什么要咖喱?

我使方法 curried,因此您可以为特定服务器定义函数,然后重用它来检查许多用户

def isMyServerAdmin = isAdmin(Some(myServer)) _

isMyServerAdmin(Some(user1)) = true
isMyServerAdmin(Some(user2)) = false
isMyServerAdmin(None) = false
于 2013-01-29T10:14:57.837 回答
2

我们可以使用Option#zip一个Option元组用户/服务器:

user zip server exists { case (user, server) => user.id == server.adminId }

其中的行为Option#zip是:

Some(User(id = "hello")) zip Some(Server(adminId = "world"))
// Some((User("hello"), Server("world")))
Some(User(id = "hello")) zip None        // None
None zip Some(Server(adminId = "world")) // None
None zip None                            // None

并且 where对 .Option#exists生成的可选元组应用谓词zip

于 2019-02-09T10:39:15.467 回答