Scalaのコードベースでの実際の実装は非常に簡潔である:
def foldLeft[B](initialValue: B)(f: (B, A) => B): B = {
//Notice that both accumulator and collectionCopy are `var`s! They are reassigned each time in the loop.
var accumulator = initialValue
//create a copy of the collection
var collectionCopy = this //the function is inside a collection class, so **this** is the collection
while (!collectionCopy.isEmpty) {
accumulator = f(accumulator , collection.head)
collectionCopy = these.tail
}
accumulator
}
編集コメントの後:
def foldLeft[B](z: B)(f: (B, A) => B): B = {
var acc = z
var these = this
while (!these.isEmpty) {
acc = f(acc, these.head)
these = these.tail
}
acc
}
は、私は明確にするためのものの名前を変更してみましょう
OPの機能を再訪して、それを命令的な方法で書き直してみましょう。 e。どうやら混乱の源である、非機能): (map /: chars)(incr)
は命令的のように書き換えることができchars.foldLeft(map)(incr)
、とまったく同じことです:
def foldLeft(initialValue: Map[Char,Int])(incrFunction: (Map[Char,Int], Char) => Map[Char,Int]): Map[Char,Int] = {
//Notice that both accumulator and charList are `var`s! They are reassigned each time in the loop.
var accumulator = initialValue
//create a copy of the collection
var charList: List[Char] = this //the function is inside a collection class, so **this** is the collection
while (!charList.isEmpty) {
accumulator = incrFunction(accumulator , collection.head)
charList = these.tail
}
accumulator
}
私はこれがfoldLeftの概念が明確になります願っています。
これは、本質的に、コレクションをトラバースしてアキュムレータを更新することによっていくらかの値を累積する必須のwhileループに対する抽象化です。アキュムレータは、アキュムレータの前の値とコレクションの現在の項目を取るユーザ提供関数を使用して更新されます。
非常に説明すると、sum、maxなどのようなコレクションのあらゆる種類の集計を計算するのに役立つだろうと考えています。スカラーコレクションは実際にこれらの関数をすべて提供しますが、あなたの質問の詳細に
、私はこれは簡単にGROUPBYを使用して行うことができることを指摘してみましょう:
def times(l: List[Char]) = l.groupBy(c => c).mapValues(_.size).toList
times(List('a','b','a')) // outputs List[(Char, Int)] = List((b,1), (a,2))
.groupBy(c => c)
はあなたにMap[Char,List[Char]] = Map(b -> List(b), a -> List(a, a))
を与えるその後、我々は、マップの値をマッピングするために.mapValues(_.size)
を使用グループ化されたサブコレクションのサイズ:Map[Char,Int] = Map(b -> 1, a -> 2)
。
最後に、.toList
のキー値タプルのリストにマップを変換して、最終結果を取得します。
最後に、あなたが言ったように出力リストの順序を気にしない場合、出力をMap[Char,Int]
として残しておくと、この決定が(リストに変換される代わりに)より良く伝わります。
'foldLeft'、' /: 'について、あるいはその両方についてご質問ですか? – pedrofurla