val wordMap = wordMap + (token,currentCount)
この行は、すでに定義されている変数を再定義しています。これを行いたい場合は、で定義wordMap
してから使用する必要がありvar
ます
wordMap = wordMap + (token,currentCount)
代わりにこれはどうですか?
io.Source.fromFile("textfile.txt") // read from the file
.getLines.flatMap{ line => // for each line
line.split("\\s+") // split the line into tokens
.groupBy(identity).mapValues(_.size) // count each token in the line
} // this produces an iterator of token counts
.toStream // make a Stream so we can groupBy
.groupBy(_._1).mapValues(_.map(_._2).sum) // combine all the per-line counts
.toList
行ごとの事前集計は、必要なメモリを削減しようとするために使用されることに注意してください。ファイル全体を一度にカウントすると、大きすぎる場合があります。
ファイルが非常に大きい場合は、Scala の並列コレクションまたは Hadoop (Scrunch や Scoobi などのクールな Scala Hadoop ラッパーの 1 つを使用) を使用して、これを並列で実行することをお勧めします (単語カウントは並列化するのが簡単なので)。
編集:詳細な説明:
わかりました、まず flatMap の内部を見てください。文字列を取得し、空白で分割します。
val line = "a b c b"
val tokens = line.split("\\s+") // Array(a, b, c, a, b)
groupBy identity is a function that just returns its argument, so if we
(identity)` では、それぞれの単語typeを各単語tokenにマッピングします。
val grouped = tokens.groupBy(identity) // Map(c -> Array(c), a -> Array(a), b -> Array(b, b))
そして最後に、各タイプのトークンの数を数えたいと思います:
val counts = grouped.mapValues(_.size) // Map(c -> 1, a -> 1, b -> 2)
これをファイル内のすべての行にマップするため、最終的には各行のトークン数になります。
それで、何をしflatMap
ますか?各行に対してトークン カウント関数を実行し、すべての結果を 1 つの大きなコレクションに結合します。
ファイルが次のとおりであると仮定します。
a b c b
b c d d d
e f c
次に、次のようになります。
val countsByLine =
io.Source.fromFile("textfile.txt") // read from the file
.getLines.flatMap{ line => // for each line
line.split("\\s+") // split the line into tokens
.groupBy(identity).mapValues(_.size) // count each token in the line
} // this produces an iterator of token counts
println(countsByLine.toList) // List((c,1), (a,1), (b,2), (c,1), (d,3), (b,1), (c,1), (e,1), (f,1))
そのため、各行のカウントを 1 つの大きなカウント セットに結合する必要があります。countsByLine
変数は であるため、メソッドIterator
はありませんgroupBy
。Stream
代わりに、基本的に遅延リストである に変換できます。開始する前にファイル全体をメモリに読み込む必要がないため、遅延が必要です。次に、groupBy
同じ単語タイプのすべてのカウントをグループ化します。
val groupedCounts = countsByLine.toStream.groupBy(_._1)
println(groupedCounts.mapValues(_.toList)) // Map(e -> List((e,1)), f -> List((f,1)), a -> List((a,1)), b -> List((b,2), (b,1)), c -> List((c,1), (c,1), (c,1)), d -> List((d,3)))
そして最後に、各タプルから 2 番目の項目 (カウント) を取得して合計することで、各単語タイプの各行のカウントを合計できます。
val totalCounts = groupedCounts.mapValues(_.map(_._2).sum)
println(totalCounts.toList)
List((e,1), (f,1), (a,1), (b,3), (c,3), (d,3))
そして、あなたはそれを持っています。