【Scala】オプション型
前回(【Scala】リストのリスト、対と組 - seconの日記)の続き
今回は10.オプション型
オプション型(Option)
Scalaでは値が存在しない可能性がある場合などにOption型を用いる。
例えば以下のようなMapがあるとき
scala> val ageMap = Map("Taro"->21, "Jiro"->19) ageMap: Map[String,Int] = Map(Taro -> 21, Jiro -> 19)
get(p)でキーが p の値が a の場合、Some(a)を返し、存在しない場合はNoneを返す
scala> ageMap.get("Taro") res: Option[Int] = Some(21) scala> ageMap.get("Saburo") res: Option[Int] = None
Some(a)に対してgetで値を取り出せる。Noneに対してgetを使用すると例外が発生する
scala> ageMap.get("Taro").get res12: Int = 21 scala> ageMap.get("Saburo").get java.util.NoSuchElementException: None.get //例外発生
Some(a)かNoneが返されるかの区別にはisEmptyを使う
scala> ageMap.get("Taro").isEmpty res16: Boolean = false scala> ageMap.get("Saburo").isEmpty res17: Boolean = true //Noneならtrueが返される
Some(a)は長さ1のリスト、None は空リストと同様の扱い。
scala> ageMap.get("Taro").filter(_>=20) //filterを使った例 res: Option[Int] = Some(21) scala> ageMap.get("Saburo").filter(_>=20) res: Option[Int] = None //Boolean型ではない scala> ageMap.get("Jiro").map(_+1) //mapも使える res24: Option[Int] = Some(20)
文字列のリストに適用した例
scala> val names = Seq("Taro","Jiro","Saburo") names: Seq[String] = List(Taro, Jiro, Saburo) scala> names.map(p => ageMap.get(p).filter(_ >= 20)) res: Seq[Option[Int]] = List(Some(21), None, None) scala> names.map(p => ageMap.get(p).map(_+1).filter(_ >=20)) res: Seq[Option[Int]] = List(Some(22), Some(20), None) //来年は20歳以上のリスト、みたいな
リスト扱いなので、連結も出来る
scala> ageMap.get("Taro") ++ ageMap.get("Jiro") res: Iterable[Int] = List(21, 19) //Iterableとなる点に注意 scala> ageMap.get("Taro") ++ ageMap.get("Saburo") res: Iterable[Int] = List(21) //None=空リストなので連結されない scala> names.map(p => ageMap.get(p)).flatten res: Seq[Int] = List(21, 19) //値のあるものだけを連結することも
Iterableはコレクション階層の上から二番目に位置するトレイト(一番上はTraversable)。
for や forMap を用いた例。
scala> names.flatMap(p => ageMap.get(p)) res: Seq[Int] = List(21, 19) >|scala| scala> for(p<-names;a<-ageMap.get(p))yield a+1 //39bytes res: Seq[Int] = List(22, 20) >|scala| scala> names.flatMap(p=>ageMap.get(p).map(_+1)) //40bytes res: Seq[Int] = List(22, 20)
このように、値の有無に関わらず統一的な処理が可能。
どうでもいいけど適当に作った式がまるっきり練習問題の答えでわろた