Scala defined two parameters, first return and then return the second

If I have option A and optionB, how can I return optionA if both are defined and option B is both undefined.

Basically, I am trying to rewrite this

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

      

No, optionA.orElse (optionB) is not the same and broke our test cases. Both options must be defined and we want to use optionA. IF optionA is defined and option B is undefined, we want None.

Someone marked my question as a duplicate that isn't there. I was having problems but finally came across an answer ....

OK, I think I got it and I definitely find it to be a less readable person

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

      

for added clarity. our truth table is thus

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

      

thank

+3


source to share


4 answers


I think the cleanest way to express what you want is if you are familiar with standard monadic operations:

optionB.flatMap(_ => optionA orElse optionB)

      

But very clear - and very fast because it avoids any object creation! - it would be easy to say in logic what you want, i.e. what you already wrote:



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

      

This is what you said ("if both are defined, I want A, otherwise I want B") - so just write it as code.

Using higher level techniques is not always the way to go, as it decreases both clarity and speed.

+3


source


Your truth table assumes that you only return a few when parameter B is specified, so we can start our evaluation by mapping on that option. Inside the map function, we know that. Then we check if we also have and a

and just return it, otherwise just use ours b

.



optionB.map(b => optionA.getOrElse(b))

      

+8


source


You can use pattern matching:

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

      

+6


source


Try the following:

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

      

+3


source







All Articles