null
null

Reputation: 9114

Replace if-without-else in Scala

How do you usually use to replace if-without-else in Scala in functional way?

For example, like this typical pattern in imperative style:

var list = List("a", "b", "c")

if (flag) { // flag is boolean variable
    // do something inside if flag is true
    list = "x" :: list
}
// if flag is false, nothing happened

I'm thinking like this to make it functional:

val tempList = List("a", "b", "c")
val list = if (flag) "x" :: tempList else tempList

Could there be a better way without using intermediary variable?

So anyone can share how do you eliminate if-without-else in scala?

Upvotes: 5

Views: 2928

Answers (3)

som-snytt
som-snytt

Reputation: 39577

You could skin the cat by making the optional part optional:

scala> val flag = true
flag: Boolean = true

scala> Option("x").filter(_ => flag).toList ::: "a" :: "b" :: "c" :: Nil
res0: List[String] = List(x, a, b, c)

scala> val flag = false
flag: Boolean = false

scala> Option("x").filter(_ => flag).toList ::: "a" :: "b" :: "c" :: Nil
res1: List[String] = List(a, b, c)

or conversely

scala> sys.props.get("flag")
res3: Option[String] = None

scala> sys.props.get("flag").map(_ => "x").toList ::: List("a","b","c")
res4: List[String] = List(a, b, c)

scala> sys.props("flag") = "true"

scala> sys.props.get("flag").map(_ => "x").toList ::: List("a","b","c")
res6: List[String] = List(x, a, b, c)

Upvotes: 2

Rex Kerr
Rex Kerr

Reputation: 167871

It's generally better to avoid cluttering your namespace with temporary variables. So something like this would be better:

val list = {
  val temp = List("a", "b", "c")
  if (flag) "x" :: temp else temp
}

or

val list = List("a", "b", "c") match {
  case x if flag => "x" :: x
  case x => x
}

If you find yourself doing this a lot and performance is not a big concern, it might be handy to define an extension method. I have one in my personal library that looks like this:

implicit class AnythingCanPickFn[A](private val underlying: A) extends AnyVal {
  /** Transforms self according to `f` for those values where `p` is true. */
  @inline def pickFn(p: A => Boolean)(f: A => A) =
    if (p(underlying)) f(underlying) else underlying
}

You'd use this one like so:

List("a", "b", "c").pickFn(_ => flag){ "x" :: _ }

Upvotes: 4

user1498953
user1498953

Reputation: 45

It can be done using scalaz's ternary operator

import scalaz._
import Scalaz._

val temp = List("a", "b", "c")
val list = (flag) ? ("x" :: temp) | temp


libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.0.6"

Upvotes: 0

Related Questions