1. ホーム
  2. スカラ

[解決済み】ScalaのfoldLeftとreduceLeftの違いについて

2022-04-11 09:17:13

質問

の基本的な違いを学びました。 foldLeftreduceLeft

foldLeftです。

  • 初期値を渡す必要がある

reduceLeftです。

  • コレクション内の最初の要素を初期値として受け取る
  • コレクションが空の場合、例外を投げる

他に違いはありますか?

同じような機能を持つ2つのメソッドを用意する具体的な理由は何ですか?

どのように解決するのですか?

実際の回答をする前に、ここでいくつか触れておきたいことがあります。

  • ご質問の内容とは関係ありません。 left リデュースとフォールディングの違いについてです。
  • 違いは実装では全くなく、シグネチャを見るだけです。
  • この質問は特にScalaとは関係なく、むしろ関数型プログラミングの2つの概念についてです。

質問に戻ります。

の署名は以下の通りです。 foldLeft (また foldRight という点を考慮して)。

def foldLeft [B] (z: B)(f: (B, A) => B): B

そして、以下がその署名です。 reduceLeft (ここでも方向は重要ではありません)

def reduceLeft [B >: A] (f: (B, A) => B): B

この2つは非常によく似ているため、混乱を招きました。 reduceLeft の特殊なケースです。 foldLeft (ちなみに、これは、あなたが 時々 は、どちらを使っても同じことを表現できます)。

を呼び出すと reduceLeft で言う List[Int] は、整数のリスト全体を文字どおりひとつの値に変換し、その値は Int (のスーパータイプ)。 Int したがって [B >: A] ).

を呼び出すと foldLeft で言う List[Int] はリスト全体を折りたたんで (紙を丸めるようなイメージで) 一つの値にまとめますが、この値は必ずしも Int (そのため [B] ).

以下はその例である。

def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
   (resultingTuple, currentInteger) =>
      (currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}

このメソッドは List[Int] を返し Tuple2[List[Int], Int] または (List[Int], Int) . これは合計を計算し、整数のリストとその合計を含むタプルを返します。ところで,リストは逆向きに返されます. foldLeft の代わりに foldRight .

見る すべてを支配する一つの折り畳み をご覧ください。