Working with Options in Scala and Play Framework, is there a more concise way of checking x amount of variables like so?
if (a.isDefined || b.isDefined || c.isDefined || d.isDefined ...) {
}
Is a one liner something like (a,b,c,d).isDefined
possible?
Thanks
On top of my head, probably there's a nicer way:
List(a, b, c, d).exists(_.isDefined)
For and
s (from Rob Starling comment):
List(a, b, c, d).forall(_.isDefined)
You could also have more complex condition compositions:
// (a || b) && (c || d)
List(
List(a, b).exists(_.isDefined),
List(c, d).exists(_.isDefined)
).forall(identity)
// (a && b) || (c && d)
List(
List(a, b).forall(_.isDefined),
List(c, d).forall(_.isDefined)
).exists(identity)
And so on.
Considering that you seem to be within the playframework and that you probably not only want to check whether the / or a value is defined but also use them, you could use the following code using the type classes of the play framework without using scalaz.
import play.api.libs.functional._
import play.api.libs.functional.syntax._
implicit def optionInstance[A] = new Applicative[Option] with Alternative[Option] {
override def pure[A](a: A): Option[A] = Option(a)
override def apply[A, B](mf: Option[(A) => B], ma: Option[A]): Option[B] = for {
f <- mf
a <- ma
} yield f(a)
override def map[A, B](m: Option[A], f: (A) => B): Option[B] = m map f
override def app: Applicative[Option] = this
override def `|`[A, B >: A](alt1: Option[A], alt2: Option[B]): Option[B] = {
(alt1, alt2) match {
case (Some(_), None) => alt1
case (None, Some(_)) => alt2
case _ => None
}
}
override def empty: Option[Nothing] = None
}
// examples
val optI = Option(3)
val optS = Option("Hello")
val optNone : Option[String] = None
(optI and optS ) {(i, s) => s"$i $s"}
(optI and optS and (optNone or Option("world")) ) { (i,s,w) => s"$i $s $w"}
On an aesthetic basis:
scala> val a,b = Some(7)
a: Some[Int] = Some(7)
b: Some[Int] = Some(7)
scala> val c,d: Option[Int] = None
c: Option[Int] = None
d: Option[Int] = None
scala> a orElse b isDefined
res0: Boolean = true
scala> c orElse d isDefined
res1: Boolean = false
scala> a orElse c isDefined
res2: Boolean = true
I could do that all day.
scala> c orElse d orElse a orElse b isDefined
res3: Boolean = true
Yup, just checking that I could do it all day.