文章目錄
  1. 1. GenTraversable
  2. 2. Flatten
    1. 2.1. List
    2. 2.2. Option
  3. 3. FlatMap
  4. 4. Reference

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 dimension
GenTraversable裡面的elements 也需要是GenTraversable

例如

1
2
scala> 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
2
3
List(1, 2, 3).flatten
<console>:11: error: No implicit view available from Int => scala.collection.GenTraversableOnce[B].
List(1, 2, 3).flatten

如果裡面的element 不是GenTraversableOnce, 會發生錯誤
1,2,3 都是Int, 不是GenTraversableOnce

1
2
3
4
5
6
7
8
private def sequential: TraversableOnce[A] = this.asInstanceOf[GenTraversableOnce[A]].seq

def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = {
val b = genericBuilder[B]
for (xs <- sequential)
b ++= asTraversable(xs).seq
b.result()
}

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
2
3
4
5
scala> val l = List(Some(4), Some(5), None)
l: List[Option[Int]] = List(Some(4), Some(5), None)

scala> l.flatten
res28: List[Int] = List(4, 5)

有趣的Option 可以implicit converted into Iterable which is subclass of GenTraversable
可以直接flatten 出value, ignore None

FlatMap

FlatMap 類似Map, 但接收的function 需要return GenTraversable,然後被flatten

1
2
scala> 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
3
res87: 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 None

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
scala> 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)

Reference

Option Cheat SHeet
FlatMap

文章評論

文章目錄
  1. 1. GenTraversable
  2. 2. Flatten
    1. 2.1. List
    2. 2.2. Option
  3. 3. FlatMap
  4. 4. Reference