[解決済み] 縮小、折りたたみ、スキャン(左/右)?
質問
を使用する必要があります。
reduceLeft
,
reduceRight
,
foldLeft
,
foldRight
,
scanLeft
または
scanRight
?
その違いについて、簡単な例を挙げて直感的に理解したいのです。
どのように解決するのですか?
一般に、6つのfold関数はすべて、コレクションの各要素に二項演算子を適用します。各ステップの結果は、次のステップに渡されます(二項演算子の2つの引数のうちの1つの入力として)。このようにして、私たちは 積算 という結果が得られます。
reduceLeft
と
reduceRight
は1つの結果を計算します。
foldLeft
と
foldRight
は、開始値を用いて一つの結果を計算します。
scanLeft
と
scanRight
は、開始値を用いて、中間的な累積結果の集合を計算する。
アキュムレート
LEFTとforwardsから...
要素の集まりで
abc
と二項演算子
add
コレクションのLEFT要素から前方に進むとき(AからCまで)、異なるfold関数が何を行うかを調べることができます。
val abc = List("A", "B", "C")
def add(res: String, x: String) = {
println(s"op: $res + $x = ${res + x}")
res + x
}
abc.reduceLeft(add)
// op: A + B = AB
// op: AB + C = ABC // accumulates value AB in *first* operator arg `res`
// res: String = ABC
abc.foldLeft("z")(add) // with start value "z"
// op: z + A = zA // initial extra operation
// op: zA + B = zAB
// op: zAB + C = zABC
// res: String = zABC
abc.scanLeft("z")(add)
// op: z + A = zA // same operations as foldLeft above...
// op: zA + B = zAB
// op: zAB + C = zABC
// res: List[String] = List(z, zA, zAB, zABC) // maps intermediate results
RIGHTと逆から...
RIGHT要素から始めて逆方向(CからA)へ進むと、今度は 第二 の引数が結果を蓄積します(演算子は同じで、役割を明確にするために引数名を入れ替えただけです)。
def add(x: String, res: String) = {
println(s"op: $x + $res = ${x + res}")
x + res
}
abc.reduceRight(add)
// op: B + C = BC
// op: A + BC = ABC // accumulates value BC in *second* operator arg `res`
// res: String = ABC
abc.foldRight("z")(add)
// op: C + z = Cz
// op: B + Cz = BCz
// op: A + BCz = ABCz
// res: String = ABCz
abc.scanRight("z")(add)
// op: C + z = Cz
// op: B + Cz = BCz
// op: A + BCz = ABCz
// res: List[String] = List(ABCz, BCz, Cz, z)
.
デキュムレーション
LEFTとforwardsから...
もし、その代わりに
デキュムレーション
コレクションの LEFT 要素から始まる引き算によって、ある結果を得るには、その結果を最初の引数
res
の二項演算子
minus
:
val xs = List(1, 2, 3, 4)
def minus(res: Int, x: Int) = {
println(s"op: $res - $x = ${res - x}")
res - x
}
xs.reduceLeft(minus)
// op: 1 - 2 = -1
// op: -1 - 3 = -4 // de-cumulates value -1 in *first* operator arg `res`
// op: -4 - 4 = -8
// res: Int = -8
xs.foldLeft(0)(minus)
// op: 0 - 1 = -1
// op: -1 - 2 = -3
// op: -3 - 3 = -6
// op: -6 - 4 = -10
// res: Int = -10
xs.scanLeft(0)(minus)
// op: 0 - 1 = -1
// op: -1 - 2 = -3
// op: -3 - 3 = -6
// op: -6 - 4 = -10
// res: List[Int] = List(0, -1, -3, -6, -10)
RIGHTと逆から...
しかし、今、xRightのバリエーションに注目してください。xRight のバリエーションで(非)累積された値が
第二
パラメータ
res
二項演算子の
minus
:
def minus(x: Int, res: Int) = {
println(s"op: $x - $res = ${x - res}")
x - res
}
xs.reduceRight(minus)
// op: 3 - 4 = -1
// op: 2 - -1 = 3 // de-cumulates value -1 in *second* operator arg `res`
// op: 1 - 3 = -2
// res: Int = -2
xs.foldRight(0)(minus)
// op: 4 - 0 = 4
// op: 3 - 4 = -1
// op: 2 - -1 = 3
// op: 1 - 3 = -2
// res: Int = -2
xs.scanRight(0)(minus)
// op: 4 - 0 = 4
// op: 3 - 4 = -1
// op: 2 - -1 = 3
// op: 1 - 3 = -2
// res: List[Int] = List(-2, 3, -1, 4, 0)
最後のList(-2, 3, -1, 4, 0)は、もしかしたら直感的に期待するものとは違うかもしれませんね
このように、foldXの代わりにscanXを実行し、各ステップで累積した結果をデバッグするだけで、foldXが何をしているかを確認することができるのです。
ボトムライン
-
で結果を積算する
reduceLeft
またはreduceRight
. -
で結果を積算する
foldLeft
またはfoldRight
開始値がある場合 -
で中間結果の集まりを集計する。
scanLeft
またはscanRight
. -
にしたい場合は、xLeftのバリエーションを使用します。 前方 をコレクションを通して表示します。
- にしたい場合は、xRightのバリエーションを使用します。 後方 をコレクションを通して表示します。
関連
-
[解決済み] Scala - case classを木のように(きれいに)印刷する方法
-
[解決済み] Scala subString関数
-
[解決済み] Spark Implicit $ for DataFrame(データフレーム用暗黙の$)。
-
[解決済み] NoClassDefFoundError: org/apache/hadoop/fs/StreamCapabilities (s3データをsparkで読み込む際に発生します。
-
[解決済み] Scala : valへの再割り当て [重複].
-
[解決済み] Scalaのcase classとclassの違いは何ですか?
-
[解決済み】コマンドラインパラメータを解析する最良の方法?[クローズド]
-
[解決済み】Scalaの名前による呼び出しと値による呼び出し、明確化の必要性
-
[解決済み] Scalaの識別子 "implicitly "とは?
-
[解決済み] Kotlinのfoldとreduceの違い、いつどちらを使うか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Scala - case classを木のように(きれいに)印刷する方法
-
[解決済み] SparkはYarnクラスタ上で動作しています exitCode=13:
-
[解決済み] Scala 無名クラスでextendsを使用する方法
-
[解決済み] Scala : valへの再割り当て [重複].
-
[解決済み] Traitの代わりに抽象クラスを使用する利点は何ですか?
-
[解決済み】Scalaのvarとvalの定義の違いは何ですか?
-
[解決済み】コマンドラインパラメータを解析する最良の方法?[クローズド]
-
[解決済み】タスクがシリアライズされない:オブジェクトではなくクラスに対してのみクロージャの外で関数を呼び出すとjava.io.NotSerializableExceptionが発生する
-
[解決済み】case objectとobjectの違いについて
-
[解決済み] Spark SQLでカラムの降順でソートするには?