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

时间:2015-06-09 19:27:09

标签: scala

如果我有optionA和optionB,如果两者都被定义且两个都没有定义,则如何返回optionA。

基本上,我正在尝试重写这个

val result: Option[Long] = 
  if(optionA.isDefined && optionB.isDefined)
     optionA
  else
     optionB

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

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

好吧,我认为我得到了它,我绝对认为它不那么人性化了

optionA.flatMap { aId =>
    optionB.map(bId => bId).orElse(Some(aId))
}

为了更加清晰。因此我们的真值表是

optionA.isDefined  optionB.isDefined   resultNeeded
    None               None               None
    Some(a)            None               None
    None               Some(b)            Some(b)
    Some(a)            Some(b)            Some(a)

感谢

4 个答案:

答案 0 :(得分:8)

你的真值表暗示你只在定义了optionB时才返回Some,所以我们可以通过映射选项来开始我们的评估。在地图功能中,我们知道我们有一个 @Override public void onClick(View v) { Bundle b = new Bundle(); b.putString("url", ""); fragment.setArguments(b); fm.beginTransaction().replace(R.id.container, fragment).commit(); fm.executePendingTransactions(); today.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_950)); monthly.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_800)); weekly.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_800)); } }); { weekly.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { fragment = new TodayFragment(); Bundle b = new Bundle(); b.putString("url", ""); fragment.setArguments(b); fm.executePendingTransactions(); fm.beginTransaction().replace(R.id.container, fragment).commit(); weekly.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_950)); monthly.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_800)); today.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_800)); } }); } monthly.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { fragment = new TodayFragment(); Bundle b = new Bundle(); b.putString("url", ""); fragment.setArguments(b); fm.executePendingTransactions(); fm.beginTransaction().replace(R.id.container, fragment).commit(); monthly.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_950)); weekly.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_800)); today.setBackgroundColor(getResources().getColor(R.color.material_blue_grey_800)); } }); 。然后我们检查是否有b并且只返回,否则只需使用我们的a

b

答案 1 :(得分:7)

您可以使用模式匹配:

(optionA, optionB) match {
  case (Some(_), Some(_)) => optionA
  case _ => optionB
}

答案 2 :(得分:4)

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

optionB.flatMap(_ => optionA orElse optionB)

但非常清楚 - 而且非常快,因为它避免了任何对象创建! - 只是在逻辑中准确地说出你想要的东西,即你已经写过的东西:

if (optionA.isDefined && optionB.isDefined) optionA else optionB

那就是你所说的("如果两者都被定义,我想要A,否则我想要B") - 所以只需把它写成代码。

当降低清晰度和速度时,使用更高级别的方法并非总是如此。

答案 3 :(得分:3)

试试这个:

(optionA,optionB) match {
   case (Some(v1) , Some(v2)) => Some(v1)
   case (_ , a:Option) => a
}