最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Scala day 29 (some collection method)

XAMPP下载 admin 656浏览 0评论
 map
對 collection 每個元素個別處理 :

scala> val lst = List(“Daniel”,”Apple”,”Mac”,”Taipei”,”Jack”,”Hello world”,”Banana”,”scala”)
lst: List[String] = List(Daniel, Apple, Mac, Taipei, Jack, Hello world, Banana, scala)

scala> lst.map(name => name.length)
res16: List[Int] = List(6, 5, 3, 6, 4, 11, 6, 5)

scala> lst.map(_.length)
res15: List[Int] = List(6, 5, 3, 6, 4, 11, 6, 5)
reduce
將 collection 的元素收集處理,第一次先處理兩個元素,產生的解果再跟下個元素處理,最後回傳跟元素一樣型態的值 :

scala> lst.map(_.length).reduce((num1:Int,num2:Int) => num1 + num2)
res17: Int = 46

scala> lst.map(name => name.length)
res16: List[Int] = List(6, 5, 3, 6, 4, 11, 6, 5)
flatten
flatten 可以將 collection 裡的 collections 轉換成一個 collection :

scala> val lst = List(List(1,2), List(3,4,List(5,6)))
lst: List[List[Any]] = List(List(1, 2), List(3, 4, List(5, 6)))

scala> lst.flatten
res26: List[Any] = List(1, 2, 3, 4, List(5, 6))
flatMap
flatMap 會先執行 map 之後再處理 flatten,相當於兩個的結合 :
下面例子會先對 List 裡的 每個 List 做 distinct,再 flatten 成一個 collection :

scala> val lst = List(List(1,2,1,2), List(5,3,4,1,5), List(2,4,6,7))
lst: List[List[Int]] = List(List(1, 2, 1, 2), List(5, 3, 4, 1, 5), List(2, 4, 6, 7))

scala> lst.flatMap(_.distinct)
res33: List[Int] = List(1, 2, 5, 3, 4, 1, 2, 4, 6, 7)

scala> lst.map(_.distinct).flatten
res34: List[Int] = List(1, 2, 5, 3, 4, 1, 2, 4, 6, 7)
distinct
distinct 可將重複的元素變成一個 :

scala> val lst = List(List(1,2), List(3,4,1,5), List(2,4,6,7))
lst: List[List[Int]] = List(List(1, 2), List(3, 4, 1, 5), List(2, 4, 6, 7))

scala> lst.flatten.distinct
res27: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
sortWith
scala> lst.sortWith(_ < _)
res20: List[String] = List(Apple, Banana, Daniel, Hello world, Jack, Mac, Taipei, scala)

scala> lst.sortWith(_ > _)
res21: List[String] = List(scala, Taipei, Mac, Jack, Hello world, Daniel, Banana, Apple)
Option、map、flatMap、sum :
在介紹 List 的時候有先介紹過這範例,不過這邊再來複習一次,會比較有感覺.
定義一個 function 將 String 轉成 Option[Int] 的 type :

scala> def toInt(s: String): Option[Int] = {
|   try {
|     Some(Integer.parseInt(s.trim))
|   } catch {
|     case e: Exception => None
|   }
| }
toInt: (s: String)Option[Int]
然後定義一組有數字及文字的 Seq[String] 的 collection,然後透過 map 對裡面每個元素做上面定義的 toInt 方法,
可以轉成 Int 的會回傳 Some(Int) 不行的回傳 None

scala> val strings = Seq(“1”, “2”, “foo”, “3”, “bar”)
strings: Seq[String] = List(1, 2, foo, 3, bar)

scala> strings.map(toInt)
res35: Seq[Option[Int]] = List(Some(1), Some(2), None, Some(3), None)
這時候透過 flatMap 展開後,None 物件會被過濾掉,而 Some(Int) 會轉成 Int :

scala> strings.flatMap(toInt)
res36: Seq[Int] = List(1, 2, 3)
最後透過 sum 將元素的值做加總 :

scala> strings.flatMap(toInt).sum
res37: Int = 6
fold
fold 有兩個參數,第一個是代初始值,第二的是 lambda expressions 就是元素要處理的事 :
下面例子初始值是 0,然後執行順序參考下面 :

scala> val numbers = List(5, 4, 8, 6, 2, 3)

 numbers: List[Int] = List(5, 4, 8, 6, 2, 3)

scala> numbers.fold(0) { (z, i) =>
|   println(z + ” , ” + i)
|   z + i
| }
0 , 5 //初始值 0 跟 第一個元素 5 相加
5 , 4 //(0 + 5) 上一個的結果跟下個元素 4 做相加
9 , 8 //上一個的結果(9)跟下個元素 4 做相加,以此類推…
17 , 6
23 , 2
25 , 3
res38: Int = 28
fold 之外還有另外兩個 foldLeft、foldRight,foldLeft 是從左邊開始,foldLeft 是從右邊開始,fold 順序不一定 :
foldLeft 範例,初始參數改成 1,從左邊開始加

scala> val numbers = List(5, 4, 8, 6, 2, 3)
numbers: List[Int] = List(5, 4, 8, 6, 2, 3)

scala> numbers.foldLeft(1) { (z, i) =>
|   println(z + ” , ” + i)
|   z + i
| }
1 , 5 //初始值 1 跟左邊第一個元素 5 相加
6 , 4 //(1 + 5) 上一個的結果 6 跟左邊第二個元素 4 作相加…
10 , 8
18 , 6
24 , 2
26 , 3
res45: Int = 29
foldRight 範例,初始參數改成 2,從右邊開始加 :

scala> numbers.foldRight(2) { (z, i) =>
|   println(z + ” , ” + i)
|   z + i
| }
3 , 2 //初始值 2 跟右邊第一個元素 3 相加
2 , 5 //(2 + 3) 上一個的結果 5 跟右邊第二個元素 2 作相加…
6 , 7
8 , 13
4 , 21
5 , 25
res46: Int = 30
最後試著了解這段 code 吧 :

scala> val lst = List(“Daniel”,”Apple”,”Mac”,”Taipei”,”Jack”,”Hello world”,”Banana”,”scala”)
lst: List[String] = List(Daniel, Apple, Mac, Taipei, Jack, Hello world, Banana, scala)

scala> lst.map(_.length).filter(_ > 4).foldLeft(List.empty[Int]) {
|   (s,ele) => if(s.contains(ele)) List(ele) else (s :+ ele)
| }.reduce(_ + _)
res47: Int = 11
總結
scala collection 提供非常多的 api,這邊只是先列幾個範例,可以再多找些資訊學習.
上述 Code 解析 :
scala> lst.map(_.length) // 將每個元素轉成該元素的長度,然後產生一組新的 List[Int]
res48: List[Int] = List(6, 5, 3, 6, 4, 11, 6, 5)

scala> List(6, 5, 3, 6, 4, 11, 6, 5).filter(_ > 4)
res49: List[Int] = List(6, 5, 6, 11, 6, 5) // 透過 filter 只取得 > 4 的元素,再產生一組新的 List[Int]

scala> List(6, 5, 6, 11, 6, 5).foldLeft(List.empty[Int]) {
|   (s,ele) => if(s.contains(ele)) List(ele) else (s :+ ele)
| } // 透過 foldLeft 初始值參數是一個空的 List 也就是(s),然後判斷左邊第一個元素 6,是否包含在 s 裡,不在就加入回傳新的 List,否則就不加入回傳原來的 List.可去除重複的元素,也可用 distinct.
res50: List[Int] = List(6, 5)

scala> List(6, 5).reduce(_ + _) //接著透過 reduce 將每個元素做相加回傳跟元素一樣的type Int
res51: Int = 11

scala> List(6, 5).sum //使用 sum 將元素做加總
res52: Int = 11

转载请注明:XAMPP中文组官网 » Scala day 29 (some collection method)

您必须 登录 才能发表评论!