最近Scalaのコレクションクラスに「groupBy」というメソッドがあることを知り、ちょっと使ってみました。
使ってみて改めて画期的なメソッドだな~と感じたのでちょっと紹介いたします。
groupbyメソッドは引数に渡した関数の戻り値をキーにしたマップを作成するメソッドです。同じキーを返した値がマップの値になります。
例として売上げを商品毎にまとめてみます。
売上げは
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Sale(itemCode:Int, number:Int) |
というケースクラスで表現します。itemCodeが商品コードでnumberが売上げ数量という形になります。
このケースクラスを利用して
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Sale(itemCode:Int, number:Int) | |
object GroupBy { | |
def main(args:Array[String]) { | |
val list = Sale(1, 2)::Sale(2, 3)::Sale(3, 4)::Sale(1, 5)::Sale(2, 6)::Sale(3, 7)::Nil | |
// 商品コード毎にまとめる | |
val groupMap = list.groupBy(_.itemCode) | |
// 結果を出力 | |
groupMap.foreach(println(_)) | |
} | |
} |
というソースを実行すると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(3,List(Sale(3,4), Sale(3,7))) | |
(1,List(Sale(1,2), Sale(1,5))) | |
(2,List(Sale(2,3), Sale(2,6))) |
と出力されます。商品コード毎のMapができています。
続いて、商品コード毎の売上数量の合計を求めるには
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val countGroup = groupMap.mapValues(_.foldLeft(0)(_ + _.number)) |
とします。countGroupの内容を出力すると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Map(3 -> 11, 1 -> 7, 2 -> 9) |
と出力されます。これを商品コードでソートするには
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val sortCountGroup = countGroup.toList.sortWith(_._1 < _._1) |
とします。
普段こういった集計処理(というほどでもないですが・・・)はSQLを利用することがほとんどだと思いますが、GAEのBigTableやKeyValueStoreのようなNoSQLなデータベース(ストレージ?)が普及してくるとプログラム内で集計処理をすることがどんどん増えてくると考えられます。
そういった中で、あらかじめこういったメソッドが用意されているなんて、ありがたいことだな~なんてちょと感動してしまいました。
最後にそれぞれの処理をまとめたプログラムを下記に記します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Sale(itemCode:Int, number:Int) | |
object GroupBy { | |
def main(args:Array[String]) { | |
val list = Sale(1, 2)::Sale(2, 3)::Sale(3, 4)::Sale(1, 5)::Sale(2, 6)::Sale(3, 7)::Nil | |
val groupMap = list.groupBy(_.itemCode) | |
groupMap.foreach(println(_)) | |
val countGroup = groupMap.mapValues(_.foldLeft(0)(_ + _.number)) | |
println(countGroup) | |
val sortCountGroup = countGroup.toList.sortWith(_._1 < _._1) | |
println(sortCountGroup) | |
sortCountGroup.foreach(tp => println(tp._1 + " => " + tp._2)) | |
} | |
} |
※追伸 >- この投稿が役にたったと思った方は、上か下の広告をクリックしていただけるとうれいいです。
0 件のコメント:
コメントを投稿