Scala基礎應用(7)- map/flatMap和filter

Scala基礎應用(7)- map/flatMap和filter

本章主要介紹集合的map, flatten, flatMap, filter zip, fold, reduce等常用方法

map

map接受一個函數作爲參數, 而此函數會接受一個參數爲集合中元素, 所以此函數用於對集合中每一個元素進行處理後,產出其結果的集合。

val test = List("a", "b", "c")
test.map(x => x.toUpperCase)
或者 test.map(_.toUpperCase)

flatten

flatten 是將嵌套集合展開一層,注意Any類型的集合是不是展開的,但集合類型是可以展開的,即使是Any類型的集合類型。

List(List(List(1,2),List(3,4)), List(5,6)).flatten 可以展開一層,元法再次調用flatten進行再次展開,因爲List(5,6)在第一次flatten時,已經展開,這個List會變成含有List和常數的List[Any]類型,下面可以進行再次展開

List(List(List(1,2),List(3,4)), List(List(5,6), List(7,8))).flatten.flatten  // 可以展開第二層

flatMap

flatMap實際上是對集合進行map, 然後將map函數處理的結果再flatten

List(List("a", "b"), List("c", "d")).flatMap (x => x)
與
List(List("a", "b"), List("c", "d")).flatten 返回的結果一樣

只是前面一個式子中,x 參數是一個List集合

List(List(1,2),List(3,4)).flatMap(x=>x.map(x=>x*2))
通過上面這個式子,也可以看出x是集合,它有map功能,同時我們也能看出map返回的也是集合,而結果是展開的,所以可以理解爲flatMap在執行完函數後,執行了flatten

filter

filter通過函數參數過濾掉函數返回false的元素

List("a", "b", "c").filter(x => x == "a")

zip

zip將兩個集合進行合併,最終結果爲較短集合的長度

val list1 = List("a", "b", "c", "d")
val list2 = List(1, 2, 3)
list1.zip(list2) 或者 list2.zip(list1)的長度都是3

可用zipAll來處理長度不同的兩個集合,那如何處理較短的集合的填充呢?

list1.zipAll(list2, "填充1", "填充2")
如果list1較短,則用"填充1"填充,如果list2較短,則用"填充2"進行填充
上例將以"填充2"填充, 因爲list2較短

fold

fold將集合元素進行處理,然後產生你想要的結果類型。

  • 樣式

    集合變量.fold(初始值) { (累集結果變量,元素) => 處理函數體}
    
    如:
    List(1,2,3,4,5).fold(0) { (sum, item) => sum + item }
    返回15
    List(1,2,3,4,5).fold("a") { (sum, item) => sum + item.toString }
    返回 a12345
    
    注意:如果初始值類型和元素類型一至,返回類型也是該類型,否則爲Any類型
  • foldLeft和foldRight分別從左開始fold和從右往左開始fold

    class Foo(val name: String, val age: Int, val genda: Symbol)
    object Foo {
        def apply(name: String, age: Int, genda: Symbol) = new Foo(name, age, genda)
    }
    
    val fooList = Foo("張三", 15, '男) :: Foo("李四", 20, '男) :: Foo("阿花", 18, '女) :: Nil
    
    val lst = fooList.foldLeft(List[String]()) {
        (z, f) =>
        val title = f.genda match {
            case '男 => "Mr."
            case '女 => "Ms."
        }
        println(z)
        z :+ s"$title ${f.name}, ${f.age}"
    }
    
    注意: foldLeft和foldRight產生的結果與初始值的類型相同
    
    另外:
    foldLeft的簡寫爲 /:
    foldRight的簡寫爲 :\
    
    (0/:(1 to 100)) (_+_)
    ((1 to 100) :\0) (_+_)

reduce

可以將reduce認爲是fold的一種特殊情況,reduce的返回值類型必須與元素的類型相同

val list1 = List(1,2,3)
list1.reduce((sum,item) => sum + item)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章