2011年5月1日 星期日

3. List 中有用的 methods

在 Scala 中 List 是常有用的資料結構,我們可以發現有許多 method 用在處理重複工作時,非常有用。其實這些 method 出現在 Traversable 中(List 繼承 Seq,Seq 繼承 Traversable),只要 繼承自  Traversable 就都可使用這些 method。

這些 method 將 function當成參數傳入,然後各個 element 對該 fucntion做運算,所以熟悉這些 method 也是熟悉 Higher order functionality 的重要基礎。

1. map
  • 傳入一單參數的 function(unary function)。
  • List 每個 element 都呼叫 map 的 function,然後產生與原來 List 相同長度的另一個 List
  • List(a1, a2, ... an) map (f) 會轉化為 List(f(a1), f(a2), ..., f(an))。
  • List(1, 2, 3) map (_ * 2)
    
    上例會得到 List(2, 4, 6)

2.reduceLeft/reduceRight
  • 傳入一個雙參數的 function(binary function)。
  • reduceLeft / reduceRight主要目的為做整合性的運算,將一個 List 的所有element透過運算,轉換成一個 element。
  • 如:找出最大、最小的那個 element。
  • reduce的意思是慢慢將element合併處理。
  • List(a1, a2, ... an) reduceLeft (f) 會轉化為 f(...f(f(a1, a2), a3),...an)。
  • reduceLft / reduceRight 輸入的 function,其 return 值要與 element 的型態相同,且 reduceLft / reduceRight 不像 foldLeft/foldRight 需要有所謂的 initial 的輸入的參數。
  • 若運算之後想得到的值,與 element 的型態不同,無法使用 reduce,需改為 foldLeft / foldRight。比如由一群人當中,相要計算年齡總和,必須使用 fold。
  • List("John", "Mary", "Jason") reduceLeft((s1, s2) =>
        if (s1.length < s2.length) s2 else s1)
    
    上例會得到 "Jason"
  • 但你若想要找到所有字串的總長度,以下的作法(使用reduceLeft)是錯誤。
    List("John", "Mary", "Jason") reduceLeft((s1, s2) => s1.length + s2.length)
    
    上例會得到 type mismatch 錯誤

3. foldLeft / foldRight
  • 傳入一個雙參數的 function(binary function)。
  • 用來將所有的 element 做一次運算。
  • List(a1, a2, ... an) flodLeft (initValue)(f) 會轉化為 f(...f(f(initBalue, a1), a2), a3),...an)。
  • 需要傳入初始值,但 輸入的 function,其 return 值不需與 element 的型態相同。因此可以用來找出各 element 值的總和。
    List("John", "Mary", "Jason").foldLeft(0)((sum, s) => sum + s.length)
    
    會得到 13
  • 可以使用 /: 取代 foldLeft, :\ 取代 foldRight(請注意冒號一定在list那邊)
    foldLeft 格式:(initValue /: list)(f)
    foldRight 格式:(list :\ initValue)(f)

    上例可以改寫為
    (0 /: List("John", "Mary", "Jason"))((sum, s) => sum + s.length)
    

4. exists
  • 傳入一個單參數的 function(unary function),其 return 型態為Boolean
  • exists用來判別是否有符和該條件的 element 存在。
  • 非所有的 element 都會找尋過一遍,只要找到有符合的 element 就會停止。
    List(1, 2, 3).exists(_ >= 2)
    
    上例會 return true

4. partition
  • 用來將 List 分割成兩部份,前面是 ture 的部份,後面是 false 的部份
  • 傳入一個單參數的 function(unary function),其 return 型態為Boolean
  • List(1, 2, 3).partition(_ >= 2)
    
    上例會 return (List(2, 3), List(1))

沒有留言:

張貼留言