我有以下代码
def my_function(condition: Int=>Boolean): Int = {
for (i <- 0 to 10)
if (condition(i)) return i
return -1
}
代码很简单:如果1到10之间的数字满足一些condition
,则返回数字,否则返回无效结果(-1)。
它工作得很好,但它违反了一些函数式编程原则,因为return
周期中的for
。我怎样才能重构这个方法(我也得到了单元测试)并删除了返回语句。我想我必须使用yield
,但它似乎产生了列表,我只需要一个值。
答案 0 :(得分: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
方法返回集合中满足条件的第一项。它将项目作为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
答案 1 :(得分:5)
您可以使用本机收集方法
def my_function(condition: Int => Boolean): Int =
(1 to 10).find(condition).getOrElse(-1)
通常在scala中你应该避免错误代码&#34;使用选项返回
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建议