Reputation: 77
enter code here
package anotherExample
object StringSplitter {
def computePercentTrue(line: String): Double = {
val splits: Array[String] = line.split(";")
var totalCount: Double = 0
//println("Hi!")
var trueCount: Double = 0
for (value <- splits) {
//println("Hello!")
val valueAsBoolean: Boolean = value.toBoolean
//println(3)
if (valueAsBoolean) {
trueCount += 1
}
totalCount += 1
}
trueCount / totalCount
}
def main(args: Array[String]): Unit = {
val testInput = "true; false; true; true; true"
val percentTrue = computePercentTrue(testInput) // expecting 0.8
println("Percentage true == " + percentTrue)
}
}
Hi, so the point of this code is given a string of boolean values(true/false) and splitting by semicolons, I'm trying to return the percentage of values that are true. I don't understand the error message and I'm new to Scala, so can someone explain what's going on? I'm getting this error message:
Exception in thread "main" java.lang.IllegalArgumentException: For input string: " false"
at scala.collection.immutable.StringLike.parseBoolean(StringLike.scala:327)
at scala.collection.immutable.StringLike.toBoolean(StringLike.scala:289)
at scala.collection.immutable.StringLike.toBoolean$(StringLike.scala:289)
at scala.collection.immutable.StringOps.toBoolean(StringOps.scala:33)
at anotherExample.StringSplitter$.$anonfun$computePercentTrue$1(StringSplitter.scala:11)
at anotherExample.StringSplitter$.$anonfun$computePercentTrue$1$adapted(StringSplitter.scala:9)
at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:36)
at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:198)
at anotherExample.StringSplitter$.computePercentTrue(StringSplitter.scala:9)
at anotherExample.StringSplitter$.main(StringSplitter.scala:23)
at anotherExample.StringSplitter.main(StringSplitter.scala)
Upvotes: 0
Views: 1652
Reputation: 51271
With a regex solution you can be a bit more forgiving of poorly formatted input.
def computePercentTrue(line: String): Double = {
val vctr = "(true|false)".r.findAllMatchIn(line)
.map(_.group(1)=="true")
.toVector
vctr.count(identity) / vctr.length.toDouble
}
computePercentTrue("true;; false;x; true=true -- true")
//res0: Double = 0.8
Upvotes: 0
Reputation: 14803
As @asanand mentioned in his comment, you should use trim.
In Scala 2.13 you can do it entirely safe (no Exception
), use this:
stringValue.trim.toBooleanOption.getOrElse(false)
Or with previous Versions:
Try(stringValue.trim.toBoolean).getOrElse(false)
See here: https://stackoverflow.com/a/54991592/2750966
By the way in Scala always try to avoid mutable state var
s.
Here an example using foldLeft
:
def computePercentTrue(line: String): Double = {
val (trueCount, totalCount) =
line.split(";")
.foldLeft((0.0, 0)){case ((count, total), value) =>
(if(value.trim.toBooleanOption.getOrElse(false))
count + 1
else
count
, total + 1)
}
trueCount / totalCount
}
Upvotes: 2