2

私は最初のScalaスクリプトをコーディングして言語の感触をつかんでいますが、何かを達成するための最良の方法については少し行き詰まっています。

私の状況は次のとおりです。N回呼び出す必要のあるメソッドがあります。このメソッドは実行ごとにIntを返し(異なる場合があり、実行にはランダムなコンポーネントがあります)、最高の実行を維持したいと考えています(これらの実行で返される最小値)。

さて、Java / Pythonのバックグラウンドから来て、変数をnull / Noneで初期化し、ifで比較します。

best = None
for...
    result = executionOfThings()
    if(best is None or result < best):
        best = result

そしてそれはそれです(セミパイソンの擬似コードはご容赦ください)。

さて、Scalaで、私は少し苦労しています。同じ効果を達成するためのオプションとパターンマッチングの使用法について読んだことがありますが、次のようなコードを作成できると思います(これは私が思いついた中で最高でした):

best match {
    case None => best = Some(res)
    case Some(x) if x > res => best = Some(res)
    case _ =>
  }

これはうまくいくと思いますが、それが最も慣用的な書き方かどうかはわかりません。それは十分に明らかですが、そのような単純な「ユースケース」には少し冗長です。

私に機能的な光を当てることができる人はいますか?

ありがとう。

4

4 に答える 4

1

min関数を使用するだけです。

(for (... executionOfThings()).min

例:

((1 to 5).map (x => 4 * x * x - (x * x * x))).min
于 2012-04-04T17:01:29.797 に答える
1

この特定の問題については、一般的ではありませんが、Int.MaxValue保証されている限り、で初期化することをお勧めしますN >= 1。それからあなたはただ

if (result < best) best = result

また、bestオプションとして、

best = best.filter(_ >= result).orElse( Some(result) )

オプション性が重要な場合 (たとえば、その可能性がN == 0あり、その場合、コードを介して個別のパスをたどらない場合)。これは、置換される可能性のあるオプションの値を処理するためのより一般的な方法です。置換されfilterていないケースを保持し、orElse必要に応じて置換を埋めるために使用します。

于 2012-04-04T15:26:42.333 に答える
1

編集: @user-unknown の提案に合わせて調整

計算全体をより機能的にするために再考することをお勧めします。避けるべき状態を変異させます。あなたのコードの再帰バージョンを考えることができます:

def calcBest[A](xs: List[A])(f: A => Int): Int = {
  def calcBest(xs: List[A], best: Int = Int.MaxValue): Int = xs match {
    // will match an empty list
    case Nil => best
    // x will hold the head of the list and rest the rest ;-)
    case x :: rest => calcBest(rest, math.min(f(x), best))
  }
  calcBest(xs)
}

で呼び出し可能calcBest(List(7,5,3,8,2))(_*2) // => res0: Int = 4

これにより、可変状態はまったくありません。

別の方法は、リストで foldLeft を使用することです。

list.foldLeft(Int.MaxValue) { case (best,x) => math.min(calculation(x),best) }

foldLeftB と PartialFunction を取り、B をTuple2[B,A] => B返します

どちらの方法も同等です。最初のものはおそらくより速く、2番目のものはより読みやすいです。どちらもリストをトラバースし、各値に対して関数を呼び出し、最小のものを返します。あなたのスニペットからどれが欲しいですか?

于 2012-04-04T16:18:12.750 に答える
0

私は別の慣用的な解決策を提供すると思いました。を使用Iterator.continuallyして、遅延評価される無限長のイテレータを作成しtake(N)、イテレータをN個の要素に制限し、を使用minして勝者を見つけることができます。

Iterator.continually { executionOfThings() }.take(N).min
于 2012-04-04T20:29:17.420 に答える