嵌套ifs的功能语法

时间:2011-08-22 22:31:01

标签: scala

有时我会编写如下代码:

val item1 = list.find(_.source.name.equals("foo"))
if (item1.isDefined) doSomething1(item1)
else {
  val item2 = list.find(_.dest.name.equals("bar"))
  if (item2.isDefined) doSomething2(item2)
  else doSomethingElse()
}

是否有人使用更好的Scala语法来放置此代码?

3 个答案:

答案 0 :(得分:6)

我把它写成

list.find(_.source.name =="foo").fold(doSomething1) {
  list.find(_.dest.name == "bar").fold(doSomething2)(doSomethingElse)
}

但这是因为我已将方法fold添加到Option,如下所示:

class FoldableOption[A](o: Option[A]) {
  def fold[Z](f: A => Z)(g: => Z) = o.map(f).getOrElse(g)
}
implicit def option_has_folds[A](o: Option[A]) = new FoldableOption(o)

如果您不想添加fold方法,还可以使用mapgetOrElse对:

list.find(_.source.name == "foo").map(doSomething1).getOrElse {
  list.find(_.dest.name == "bar").map(doSomething2).getOrElse(doSomethingElse)
}

这不是更详细。

答案 1 :(得分:2)

除了凯文所说的,如果这些表达式返回某些内容会更好。我会做与你相同的事情,但有一个不同的具体例子:

val list = List(1,2,3,4)
val result = list.find(_ == 1).map(
  _ => "Found1").orElse(list.find(_ == 5).map(
    _ => "Found2")).getOrElse("Found3")

然而,你的看起来可能更好:)但避免副作用。将if / else链或monad链作为一个表达式来评估某种东西而不是一些奇怪的副作用。

答案 2 :(得分:0)

这应该有用,虽然它会稍慢:

val item1 = list find (_.source.name == "foo")
val item2 = list find (_.dest.name == "bar")
item1 map (doSomething1) orElse {
  item2 map (doSomething2)
} getOrElse doSomethingElse()

更新:更有效率,但不是很整洁:

val item1 = list find (_.source.name == "foo")
item1 map (doSomething1) orElse {
  val item2 = list find (_.dest.name == "bar")
  item2 map (doSomething2)
} getOrElse doSomethingElse()