5

我有以下一段代码

def my_function(condition: Int=>Boolean): Int = {
  for (i <- 0 to 10)
    if (condition(i)) return i

  return -1
}

代码很简单:如果condition满足 1 到 10 之间的数字,则返回该数字,否则返回无效结果 (-1)。

它工作得很好,但它违反了一些函数式编程原则,因为returnfor循环中。我怎样才能重构这个方法(我也有单元测试)并删除返回语句。我想我必须使用yield,但它似乎产生列表,我只需要一个值。

4

2 回答 2

13

这是您的代码的功能翻译:

def my_function(condition: Int => Boolean): Int = {
  (0 to 10).find(i => condition(i)).getOrElse(-1)
}

或者更简洁地说:

def my_function(condition: Int => Boolean): Int = {
  (0 to 10).find(condition).getOrElse(-1)
}

我使用了find将产生布尔值的函数作为参数的方法。该find方法返回集合中满足条件的第一项。它将项目作为 an 返回,Option因此如果没有令人满意的项目,则结果将为None。的getOrElse方法Option如果有则返回找到的结果,如果没有则返回-1

但是,您不应该使用“错误代码”,例如在 Scala 编程中返回 -1。他们是不好的做法。相反,您应该抛出异常或返回一个Option[Int]这样的返回None值表示未找到任何值。正确的方法是这样的:

def my_function(condition: Int => Boolean): Option[Int] = {
  (0 to 10).find(condition)
}

println(my_function(_ > 5))   // Some(6)
println(my_function(_ > 11))  // None
于 2012-09-26T10:49:02.437 回答
5

您可以使用本机收集方法

def my_function(condition: Int => Boolean): Int =
  (1 to 10).find(condition).getOrElse(-1)

通常在 scala 中,您应该使用 Option 返回来避免“错误代码”

def my_function(condition: Int => Boolean) : Option[Int] =
  (1 to 10).find(condition)

同样,您可以使用 for-yield 理解

def my_function(condition: Int => Boolean): Int =
  (for (i <- 1 to 10; if condition(i)) yield i).headOption.getOrElse(-1)

或带有选项

def my_function(condition: Int => Boolean): Int =
  (for (i <- 1 to 10; if condition(i)) yield i).headOption

或使用递归作为@Jan 的建议

于 2012-09-26T11:19:57.260 回答