I am new to Scala and I am finding the need to convert a Boolean value to an Integer. I know I can use something like if (x) 1 else 0
but I would like to know if there is a preferred method, or something built into the language (i.e. toInt()
).
If you want to mix Boolean
and Int
operation use an implicit
as above but without creating a class:
implicit def bool2int(b:Boolean) = if (b) 1 else 0
scala> false:Int
res4: Int = 0
scala> true:Int
res5: Int = 1
scala> val b=true
b: Boolean = true
scala> 2*b+1
res2: Int = 3
"insert into blah (boolVal) values (" + b + ")"
, will it automatically assume its the int version and not the bool version? –
Kliber "insert into blah (boolVal) values (" + (b:Int) + ")"
–
Silken import scala.language.implicitConversions
- docs.scala-lang.org/tutorials/tour/implicit-conversions.html –
Seedtime You can do this easily with implicit conversions:
class asInt(b: Boolean) {
def toInt = if(b) 1 else 0
}
implicit def convertBooleanToInt(b: Boolean) = new asInt(b)
Then, you will get something like
scala> false toInt
res1: Int = 0
While using an implicit
is probably the best way to go, if you want a quick-and-dirty conversion from boolean
to int
you can use boolean.compare(false)
Actually, I'd expect it to be if (x) 1 else 0
, not if (x) 0 else 1
.
That's why you should write your own conversions. Integer isn't a boolean, and if you want for some reason to store booleans as integers, then you should hone your own standards of how the truth and not truth are represented.
Boolean "true" is not a number, it is an instance of the Boolean type. Like java.lang.Boolean.TRUE
. It can be stored internally as an integer, but that is an implementation detail that shouldn't be leaked into the language.
I'd say that if (x) 0 else 1
is the preferred method of conversion. It is simple and fast.
You can also write x match {case true => 0; case false => 1}
if you want to use a more general pattern matching approach.
Since Scala 2.10 the solution by Jackson Davis is more often written using an implicit value class:
implicit class BoolToInt(val b:Boolean) extends AnyVal {
def toInt: Int = if (b) 1 else 0
def * (x:Int): Int = if (b) x else 0
}
For added comfort I have also added a multiplication operator, as this is the most common use of a Boolean to Int conversion for me. I prefer this over making the conversion itself implicit (solution provided by Patrick), as that loses more of the type control than I want.
If you don't want to go the implicit way, this may be useful:
var myBool:Boolean = true
myBool: Boolean = true
myBool.compare(false)
res3: Int = 1
myBool = false
myBool: Boolean = false
myBool.compare(false)
res3: Int = 0
Building on Paul and Gaurav's answers, the closest to a built-in might be b.compare(false).sign
. This guarantees that you're getting 0 or 1 and arguably conveys the Iverson bracket intent.
In general, I agree with some of the comments that it's preferable to avoid branching constructs in favor of straight-line method invocations. That's why the API provides methods like getOrElse
.
© 2022 - 2024 — McMap. All rights reserved.
implicit def ib (b:Boolean) = if (b) 1 else 0
although I prefer the muxes:def mux[T](cond: Boolean, yes: => T, no: => T) = if (cond) yes else no
(Scala generously enabled them via by deferred=>
arguments) enablingmux(cond, 1,-1)
instead of bulkyif (cond) 1 else -1
. – Mildamilde