I have code like that:
optionBoolean.getOrElse(false) && otherOptionBoolean.getOrElse(false)
And Scalastyle tells me that it can be simplified. How?
I have code like that:
optionBoolean.getOrElse(false) && otherOptionBoolean.getOrElse(false)
And Scalastyle tells me that it can be simplified. How?
You can try the following:
Seq(optionBoolean, otherOptionBoolean).forall(_.contains(true))
In Scala 2.13 (it is very similar in prior versions) the forall
method is located at IterableOnce
, and its implementation is:
def forall(p: A => Boolean): Boolean = {
var res = true
val it = iterator
while (res && it.hasNext) res = p(it.next())
res
}
Therefore once there is a value that doesn't satisfy the condition, the loop will break, and the rest will not be tested.
Code run at Scastie.
forall
and one contains
). In your approach, if you want to add more Booleans, you have to repeat getOrElse
for each off them. In my approach, you just add them to the Seq
. In other words, I do 2 operations no matter how many Booleans I have, and you do 1 for every Boolean. Having said that, it is the same time efficiency, but I think that mine is more readable. –
Pierro List
, fills it (two memory allocations), then iterates over it. So it is really not a "simple" solution in term of execution. Much simpler and more efficient to just test each option in turn. –
Xanthe contains
only once. The original solution repeats getOrElse
and yours repeats contians
. But in my opinion it is just a matter of style for such a simple question. for such a simple code both are valid. The question is what are we doing when the code complicates and we have for example a hundred of optional booleans. –
Pierro This is perhaps a bit clearer:
optionBoolean.contains(true) && otherOptionBoolean.contains(true)
Just to throw another, not-necessarily-better answer on the pile,
optionBoolean == Some(true) && otherOptionBoolean == Some(true)
or even
(optionBoolean, otherOptionBoolean) == (Some(true), Some(true))
What about custom dsl, that let you work with Option[Boolean]
like if is was a Boolean
? With all the same operators and same behavior.
You can use something like this:
object Booleans {
def and(fb: Option[Boolean], other: => Option[Boolean]): Option[Boolean] =
fb.flatMap(b => if (!b) Some(false) else other)
def or(fb: Option[Boolean], other: => Option[Boolean]): Option[Boolean] =
fb.flatMap(b => if (b) Some(true) else other)
def negate(fb: Option[Boolean]): Option[Boolean] =
fb.map(!_)
object Implicits {
implicit class OptionBooleanDecorator(val fb: Option[Boolean]) extends AnyVal {
def &&(other: => Option[Boolean]): Option[Boolean] =
and(fb, other)
def ||(other: => Option[Boolean]): Option[Boolean] =
or(fb, other)
def unary_!(): Option[Boolean] = negate(fb)
}
}
}
and somewhere in code:
import Booleans.Implicits._
val b1 = Some(true)
val b2 = Some(true)
val b3 = b1 && b2
val b4 = b1 || b2
val b5 = !b1
You can make it work with any other container. This sort of dsl's that extend some type are quite common in Scala world.
edit:
As for last part, namely orElse
method - this could be also placed into the dsl, but in this case you loose in composability of operations. So I let all methods return an Option
.
&&
. It's confusing if not knowing that there are implicits behind. Additionally, it's not applicable to the question. You still have to do (optionBoolean && otherOptionBoolean).getOrElse(false)
–
Adrianadriana orElse
- this could be also placed into the dsl, but in this case you loose in composability of operations. –
Baht © 2022 - 2024 — McMap. All rights reserved.
Option
exists
function – Hakodateexists
asotherOptionBoolean.exists(identity)
but I don't think it's simpler thangetOrElse
– Adrianadriana