跳轉到內容

Scala/高階函式 1

來自華夏公益教科書

高階函式是接受函式作為引數或返回函式的函式。透過使用函式而不是更簡單的值,高階函式變得非常靈活。一個簡單的例子是測試列表中至少一個元素是否透過某個測試。透過使用為 List 定義的現有高階函式,我們無需編寫測試每個元素的程式碼,而只需編寫包含測試本身的函式。例如,假設我們想測試某個列表是否包含數字 4

def isEqualToFour(a:Int) = a == 4
val list = List(1, 2, 3, 4)
val resultExists4 = list.exists(isEqualToFour)
println(resultExists4) //Prints "true".

在上面的例子中,我們首先定義包含測試的函式(等於 4)。然後我們定義一個列表,它恰好包含數字 4(這意味著最終結果應該為真)。在第三行,我們呼叫方法“exists”,它接受包含測試的函式,將其應用於列表的元素,並返回該函式是否至少對其中一個元素為真。由於該列表確實包含 4,因此最終結果為真,這也是列印的結果。

如果我們想要測試列表中所有數字是否都等於 4(顯然是假的),我們會使用“forall”方法。 "forall" 測試給定函式是否對列表中的每個元素都為真。

val resultForall4 = list.forall(isEqualToFour)
println(resultForall4) //Prints "false".

正如預期的那樣,結果為假。注意,我們不必重新定義包含測試的函式。透過將測試分離到測試函式(“isEqualToFour”)中,並將應用測試函式的邏輯分離到高階函式(“exists”和“forall”)中,我們避免了大量的重複。

另一個常見的高階函式是“map”。假設你有一個數字列表,並希望獨立地更改列表中的每個數字,例如將每個數字乘以某個常數。這正是“map”所做的:它接受一個轉換函式,並將其獨立地應用於每個元素以建立新的列表。讓我們看看它的實際應用

def multiplyBy42(a:Int) = 42*a
val resultMultiplyBy42 = list.map(multiplyBy42)
println(resultMultiplyBy42) //Prints "List(42, 84, 126, 168)".

透過使用“map”,我們避免了將函式應用於每個元素並自己構建新列表。

除了 List 之外,還有許多其他高階函式定義在大多數其他集合中,以及 Scala 庫中的其他類中。一些值得注意的函式包括“reduce”和“foldLeft”/“foldRight”。

“reduce”接受一個函式,該函式接受兩個元素並以某種方式將它們組合成一個相同型別的新元素,並一直這樣做,直到只剩下一種結果元素。 "reduce" 的使用示例包括當你想要找到一些數字的總和或總積,或者想將許多字串組合成一個字串,也許是在後續字串之間插入類似 "\n"、"," 或 ";" 之類的東西。

“foldLeft”/“foldRight”基本上是順序轉換。雖然“map”接受每個元素並獨立地對其進行轉換,但摺疊會依次遍歷集合,接受每個元素和之前的結果,並將其轉換為新結果(例如新列表或總和)。摺疊比“map”和“reduce”更難使用,但更靈活,實際上可以用來定義“map”和“reduce”本身。“Left”和“Right”指的是摺疊遍歷元素的方向。

華夏公益教科書