突っ走り書き

見せるほどのものでは..

【ひとことScala】リストからヒストグラムを作成する

Scalaならリストのヒストグラムも簡単に作成できる!って話。
エントリ名の「ひとこと」ってのは、「1センテンスで」という意味です。

groupBy と map メソッドを使って

(ある文字列, その文字列の出現回数)からなるマップを生成しています。

scala> val l = List("a", "b", "a", "c", "b", "a")
l: List[String] = List(a, b, a, c, b, a)

scala> l.groupBy(identity).map{ case (k, v) => (k, v.size) }
res1: Map[String,Int] = Map(c -> 1, a -> 3, b -> 2)

"a"が3回、"b"が2回、"c"が1回出現していることが分かります。

groupBy がポイント

Map#groupByは xs.groupBy(f) のように呼び出して、
リスト xs から判別関数 f の返り値を値にしたマップを作成できます。
下の例では、先頭文字によって文字列のリストを分類しています。

scala> val ws = List("no", "in", "no", "of", "on")
ws: List[String] = List(no, in, no, of, on)

scala> ws.groupBy(_(0))
res1: Map[Char,List[String]] = Map(n -> List(no, no), i -> List(in), o -> List(of, on))

先のヒストグラムのコードでは、内部で下のようなマップが生成されています。

scala> val l = List("a", "b", "a", "c", "b", "a")
l: List[String] = List(a, b, a, c, b, a)

scala> l.groupBy(identity)
res0: Map[String,List[String]] = Map(c -> List(c), a -> List(a, a, a), b -> List(b, b))