在Scala中替换if-without-else

时间:2015-02-01 14:29:56

标签: scala functional-programming

你通常如何使用功能方式替换Scala中的if-without-else?

例如,像命令式风格的典型模式一样:

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

我这样想是为了让它发挥作用:

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

没有使用中间变量会有更好的方法吗?

所以任何人都可以分享如何在scala中消除if-without-else?

3 个答案:

答案 0 :(得分:4)

通常最好避免使用临时变量来混淆命名空间。所以这样的事情会更好:

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

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

如果您发现自己这样做 lot 并且性能不是一个大问题,那么定义扩展方法可能很方便。我的个人图书馆中有一个看起来像这样:

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
}

您可以像这样使用这个:

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

答案 1 :(得分:2)

您可以通过将可选部分设为可选部件来遮蔽猫:

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)

或相反

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)

答案 2 :(得分:0)

可以使用scalaz的三元运算符

完成
import scalaz._
import Scalaz._

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


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