Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning true if all items in a list are true, otherwise false

Tags:

scala

I want to return true if "inStock" key exists AND all values in the list are true. If not, then return false.

val product = Map("ids" -> List("1" ,"2", "3"), "inStock" -> List("true", "false", "true", "true"))

product.get("inStock").map(x => x.forall(true))  // doesnt' work currently

<console>:13: error: type mismatch;
 found   : Boolean(true)
 required: String => Boolean

I should also safely parse the string value to a boolean like:

Try(x.toBoolean)
like image 654
cool breeze Avatar asked Oct 28 '25 08:10

cool breeze


1 Answers

You need not convert to Boolean type

product.get("inStock").map(_.forall(_ == "true")).getOrElse(false)

Beware below line can throw exception if inStock key is not present in the map.

product("inStock").forall(_ == "true")

Scala REPL

scala> val product = Map("ids" -> List("1" ,"2", "3"), "inStock" -> List("true", "false", "true", "true"))
product: Map[String, List[String]] = Map("ids" -> List("1", "2", "3"), "inStock" -> List("true", "false", "true", "true"))

scala> import scala.util._
import scala.util._

scala> product.get("inStock").map(_.forall(_ == "true")).getOrElse(false)
res7: Boolean = false

scala> product.get("foo").map(_.forall(_ == "true")).getOrElse(false)
res8: Boolean = false

Lurking Danger with NoSuchElementException

scala> product("foo").forall(_ == "true")
java.util.NoSuchElementException: key not found: foo
  scala.collection.MapLike$class.default(MapLike.scala:228)
  scala.collection.AbstractMap.default(Map.scala:59)
  scala.collection.MapLike$class.apply(MapLike.scala:141)
  scala.collection.AbstractMap.apply(Map.scala:59)
  $sess.cmd9$.<init>(cmd9.sc:1)
  $sess.cmd9$.<clinit>(cmd9.sc:-1)

Fool proof way

scala> product.get("foo").map(_.forall(_ == "true")).getOrElse(false)
res7: Boolean = false

More typesafe

product.get("inStock")
  .toSeq.flatten.map(elem => Try(elem.toBoolean))
  .collect { case Success(value) => value}
  .reduce(_ && _)

for comprehension

Use the fact that Option is an iterable.

(for {
    list <- product.get("inStock").iterator
    elem <- list.iterator
    result <- Try(elem.toBoolean).toOption.iterator
  } yield result).reduce(_ && _)
like image 113
pamu Avatar answered Oct 30 '25 00:10

pamu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!