5

次のコードがあります

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

  return -1
}

コードは単純です: condition1 から 10 までの数値が一致する場合はその数値を返し、そうでない場合は無効な結果 (-1) を返します。

returnこれは完全に正常に動作しますが、サイクル内にあるため、関数型プログラミングの原則の一部に違反していforます。このメソッドをリファクタリングして (単体テストも取得しました)、return ステートメントを削除するにはどうすればよいですか。を使用する必要があると思いますがyield、リストが生成されるようです。必要な値は1つだけです。

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メソッドは、条件を満たすコレクション内の最初のアイテムを返します。アイテムを として返す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 return を使用して「エラー コード」を回避する必要があります。

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 に答える