Scala-flatten-flatMap
更新日期:
GenTraversable
GenTraversable
可理解為可以被loop…被transverse(look over, examine)
GenTraversable: A trait for all traversable collections which may possibly have their operations implemented in parallel.
Common sub-classes: List, Map, Option
GenTraversable內的super class是GenTraversableOnce (多了Once)
Flatten
Flatten 的作用是將GenTraversable
裡面的elements的elements 取出, 變做one dimensionGenTraversable
裡面的elements 也需要是GenTraversable
例如1
2scala> List(List(4, 6), List(3,4)).flatten
res40: List[Int] = List(4, 6, 3, 4)
List 是GenTraversable,而他也包含了兩個List elements(也是GenTraversable)
flatten 就是將List(4, 6)抽出4, 6 和List(3,4) 抽出3, 4 變做one dimension
List
1 | List(1, 2, 3).flatten |
如果裡面的element 不是GenTraversableOnce
, 會發生錯誤
1,2,3 都是Int, 不是GenTraversableOnce
1 | private def sequential: TraversableOnce[A] = this.asInstanceOf[GenTraversableOnce[A]].seq |
From source code: 如果是instance of GenTraversableOnce巳經可以被flatten
Option
trait Iterable[+A] extends Traversable[A] with GenIterable[A] with GenericTraversableTemplate[A, Iterable] with IterableLike[A, Iterable[A]]
1 | scala> val l = List(Some(4), Some(5), None) |
有趣的Option 可以implicit converted into Iterable which is subclass of GenTraversable
可以直接flatten 出value, ignore None
FlatMap
FlatMap 類似Map, 但接收的function 需要return GenTraversable
,然後被flatten1
2scala> val l = List(List(3, 4), (3, 4)).map (x => List(x)).flatten
l: List[Product with java.io.Serializable] = List(List(3, 4), (3,4))
To combine with Option
1
2
3res87: List[Option[Int]] = List(Some(4), Some(5), None)
scala> l.flatMap( x => x)
res88: List[Int] = List(4, 5)
It may looks very useless, but it could be used with exception
return Some(value) if everthing is OK
otherwise just return None1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18scala> val n = List(1,2,3,4)
n: List[Int] = List(1, 2, 3, 4)
scala> n.flatMap( x => if (x > 2) Some (x) else Nne)
def toInt(in: String): Option[Int] = {
try {
Some(Integer.parseInt(in.trim))
} catch {
case e: Exception => None
}
}
scala> val s = List("1", "2", "god", "jason")
s: List[String] = List(1, 2, god, jason)
scala> s.flatMap(toInt(_))
res93: List[Int] = List(1, 2)