Edited at

Scalaでforとかmapとかを理解するためにサンプルコードで試してみた

More than 1 year has passed since last update.


概要

最近、Scalaのソースを見るようになって、forとかmapとかをけっこう使ってるなと感じました。考え方としてはharry0000さんのfor式のforeach/flatMap(map)展開についてに書いてある内容なのですが、Javaとかと違って関数型特有の書き方の感じがするので、自分でサンプルコード作って動作を確認しました。


前提

事前に下記のようなInt型のOptionのListを用意します。この中身を取得するサンプルコードを作っています。

// OptionのListを用意

val optionList = List[Option[Int]](Some(1) ,Some(2) ,Some(3) ,Some(4))


サンプルコード

1_mapで展開して中身を1足してみる

2_foreachで展開して中身を1足してみる

3_flatMapで展開して中身を1足してみる

4_flattenで展開

5_for式で展開して中身を1足してみる


1_mapで展開して中身を1足してみる

Listの中身をmapで展開して1足したものを返すメソッドです。

  // mapで展開

def usingMapPlusOne(optionList:List[Option[Int]]):List[Option[Int]] = {
optionList.map(_.map(_ + 1))
}

戻り値はList[Option[Int]]になるので、戻り値を出力するとこのような結果になります。

List(Some(2), Some(3), Some(4), Some(5))


2_foreachで展開して中身を1足してみる

Listの中身をforeachで展開して1足したものを出力するメソッドです。foreachは返り値を返さない(Unit)なので、取得したものをそのまま出力します。

  // foreachで展開

def usingForaeachPlusOne(optionList:List[Option[Int]]):Unit = {
// 出力用に1プラスしてprint
def printPlusOne(num:Int):Unit = println(num + 1)
optionList.foreach(_.foreach( printPlusOne(_) ) )
}

結果は下記の通りとなります。

2

3
4
5


3_flatMapで展開して中身を1足してみる

Listの中身をflatMapで展開して1足したものを返すメソッドです。

  // flatMapで展開

def usingFlatMapPlusOne(optionList:List[Option[Int]]):List[Int] = {
// 出力用に1プラス
def plusOne(num:Int):Option[Int] = Some(num + 1)
optionList.flatMap( _.flatMap( plusOne(_) ) )
}

mapとの違いはOption型ではなく、展開された状態のリストで戻り値が返ります。

List(2, 3, 4, 5)


4_flattenで展開

Listの中身をflattenで展開してみます。

  // flattenで展開

def usingFlatten(optionList:List[Option[Int]]):List[Int] = {
optionList.flatten
}

基本的にはflatMapと機能的には同じですが、簡単に中身を展開できます。

List(1, 2, 3, 4)


5_for式で展開して中身を1足してみる

最後はfor式で展開して1足したものを返すメソッドです。

  // for式で展開

def usingForPlusOne(optionList:List[Option[Int]]):List[Int] = {
for{
numberOption <- optionList
number <- numberOption

} yield{
number + 1
}
}

これでfaltMapと同じ形式で、展開された状態のリストで戻り値が返ります。

List(2, 3, 4, 5)