scala定义了两个选项,先返回,否则返回第二个

Dea*_*ler 4 scala

如果我有optionA和optionB,如果两者都被定义并且optionB都未定义,我怎么能返回optionA.

基本上,我试图改写这个

val result: Option[Long] = 
  if(optionA.isDefined && optionB.isDefined)
     optionA
  else
     optionB
Run Code Online (Sandbox Code Playgroud)

不,optionA.orElse(optionB)不一样,打破了我们的测试用例.必须定义两个选项,我们要使用optionA.如果定义了optionA并且未定义optionB,则我们需要None.

有人将我的问题标记为重复,但事实并非如此.我遇到了麻烦,但最终偶然发现了答案....

好吧,我想我明白了,我绝对认为它不那么人性化了

optionA.flatMap { aId =>
    optionB.map(bId => bId).orElse(Some(aId))
}
Run Code Online (Sandbox Code Playgroud)

为了更清晰.因此,我们的真值表

optionA.isDefined  optionB.isDefined   resultNeeded
    None               None               None
    Some(a)            None               None
    None               Some(b)            Some(b)
    Some(a)            Some(b)            Some(a)
Run Code Online (Sandbox Code Playgroud)

谢谢

Kar*_*arl 8

你的真值表意味着你只有在定义了optionB时才返回Some,所以我们可以通过映射该选项来开始我们的评估.在地图功能里面,我们知道我们有一个b.然后我们检查是否有一个a也只是返回,否则只需使用我们的b.

optionB.map(b => optionA.getOrElse(b))
Run Code Online (Sandbox Code Playgroud)


Mar*_*rth 7

您可以使用模式匹配:

(optionA, optionB) match {
  case (Some(_), Some(_)) => optionA
  case _ => optionB
}
Run Code Online (Sandbox Code Playgroud)


Rex*_*err 5

如果您熟悉标准的monadic操作,我认为表达您想要的最干净的方法是:

optionB.flatMap(_ => optionA orElse optionB)
Run Code Online (Sandbox Code Playgroud)

但是非常清楚-速度非常快,因为它避免了任何对象的创建!-只能在逻辑上准确地说出您想要的内容,即您已经编写的内容:

if (optionA.isDefined && optionB.isDefined) optionA else optionB
Run Code Online (Sandbox Code Playgroud)

那就是您所说的(“如果都定义了,我想要A,否则我想要B”),因此只需将其写为代码即可。

当使用高级方法降低清晰度和速度时,并非总是可行的方法。