Scala从for循环返回一个值

fic*_*ion 5 functional-programming scala

我有以下代码

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

  return -1
}
Run Code Online (Sandbox Code Playgroud)

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

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

dhg*_*dhg 13

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

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

或者更简洁地说:

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

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

但是,你应该不会用"错误代码"好像回到-1 Scala编程.他们是不好的做法.相反,你应该抛出一个异常或返回一个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
Run Code Online (Sandbox Code Playgroud)


Fed*_*aso 5

您可以使用本机收集方法

def my_function(condition: Int => Boolean): Int =
  (1 to 10).find(condition).getOrElse(-1)
Run Code Online (Sandbox Code Playgroud)

通常在scala中,您应该使用Option return来避免"错误代码"

def my_function(condition: Int => Boolean) : Option[Int] =
  (1 to 10).find(condition)
Run Code Online (Sandbox Code Playgroud)

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

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

或选项

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

或使用递归作为@Jan建议