深入探討 F# List Module 所提供的 Function (Q ~ Z)
- Version
- List.reduce
- List.reduceBack
- List.replicate
- List.rev
- List.scan
- List.scanBack
- List.singleton
- List.skip
- List.skipWhile
- List.sort
- List.sortDescending
- List.sortBy
- List.sortByDescending
- List.sortWith
- List.splitAt
- List.splitInto
- List.sum
- List.sumBy
- List.tail
- List.take
- List.takeWhild
- List.toArray
- List.toSeq
- List.transpose
- List.truncate
- List.tryFind
- List.tryFindBack
- List.tryFindIndex
- List.tryFindIndexBack
- List.tryHead
- List.tryItem
- List.tryLast
- List.tryPick
- List.unfold
- List.unzip
- List.unzip3
- List.where
- List.windowed
- List.zip
- List.zip3
- Conclusion
- Reference
F# 的 List module 提供眾多 List
常用的 Higher Order Function,要能發揮 FP 的威力,首先必須能活用內建 function。
本文探討英文字母 Q ~ Z 開頭的 function。
Version
macOS High Sierra 10.13.3
.NET Core SDK 2.1.101
Rider 2017.3.1
F# 4.1
List.reduce
將 list 中每個 element 的值經過 reduction function 累加
reduction : ('T -> 'T -> 'T) -> list : 'T list -> 'T
1 | [ 1; 2; 3 ] |
Q :
List.fold()
與List.reduce()
有何差異?
1 | [ 1; 2; 3 ] |
相同
- 都是
累加
相異
List.fold()
可以設定初始值;List.reduce()
不能設定初始值List.fold()
可以不同型別,如(string * int) list
-> int;List.reduce()
從頭到尾必須相同型別,如int lint -> int
List.reduceBack
將 list 中每個 element 的值從尾部經過 reduction function 累加
reduction : ('T -> 'T -> 'T) -> list : 'T list -> 'T
1 | [ 1; 2; 3 ] |
List.replicate
以相同 element 建立 list
count : int -> initial : 'T -> 'T list
1 | List.replicate 3 0 |
List.rev
將 list 反過來表示
list : 'T list -> 'T list
1 | [ 1; 2; 3 ] |
List.scan
類似
List.fold()
與List.reduce()
對 list 進行累加,但會將計算過程保留在新 list 的 element
folder : ('State -> 'T -> 'State) -> state : 'State -> list : 'T list -> 'State list
1 | [ 1; 2; 3 ] |
List.scanBack
同
List.scan()
,但從 list 尾部開始累加,並將最後結果先顯示
folder : ('T -> 'State -> 'State) -> list : 'T list -> state : 'State -> 'State list
1 | let list1 = [ 1; 2; 3 ] |
List.singleton
將整個 list 成為新 list 的第一個 element
value : 'T -> 'T list
1 | [ 1; 2; 3 ] |
List.skip
忽略前 n 個 element 並傳回新 list
count : int -> list : 'T list -> 'T list
1 | [ 1 .. 10 ] |
List.skipWhile
忽略前 n 個符合 predicate function 的 element,若第一個 element 不符合則停止 skip
predicate : ('T -> bool) -> list : 'T list -> 'T list
1 | [ 1 .. 10 ] |
List.sort
將 list 排序 (由小到大)
list : 'T list -> 'T list
1 | [ 3; 2; 1 ] |
List.sortDescending
將 list 排序 (由大到小)
list : 'T list -> 'T list
1 | [ 1; 2; 3 ] |
List.sortBy
將 list 的 element 透過 projection function 轉換過,再根據 key 排序 (由小到大)
projection : ('T -> 'Key) -> list : 'T list -> 'T list
1 | [ 3; 2; 1 ] |
List.sortByDescending
將 list 的 element 透過 projection function 轉換過,再根據 key 排序 (由大到小)
projection : ('T -> 'Key) -> list : 'T list -> 'T list
1 | [ 1; 2; 3 ] |
List.sortWith
將 list 的 element 透過 comparer function 排序
comparer : ('T -> 'T -> int) -> list : 'T list -> 'T list
1 | [ 3; 2; 1 ] |
List.splitAt
將 list 根據指定 index 分成兩個 list
index : int -> list : 'T list -> 'T list * 'T list
1 | [ 1 .. 10 ] |
List.splitInto
將 list 分成指定 chunk 數
count : int -> list : 'T list -> 'T list list
1 | [ 1 .. 10 ] |
List.sum
將 list 中所有 element 相加
list : 'T list -> 'T
1 | [ 1; 2; 3 ] |
List.sumBy
將 list 先將過 projection function 運算後再相加,相當於
List.map()
+List.sum()
projection : ('T -> 'U) -> list : 'T list -> 'U
1 | [ 1; 2; 3 ] |
相當於
1 | [ 1; 2; 3 ] |
List.tail
將 list 除了第 1 個 element 外,剩下的 list 傳回,相當於 list 的
Tail
property
list : 'T list -> 'T list
1 | [ 1; 2; 3 ] |
List.take
回傳 list 前 n 個 element
count : int -> list : 'T list -> 'T list
1 | [ 1 .. 10 ] |
Q :
List.truncate()
與List.take()
有何差異?
當 n 大於 Length
時,List.truncate()
不會報錯,只是將整個 list 傳回;但 List.take()
拋出 InvalidOperationException
List.takeWhild
回傳前 n 個符合 predicate function 的 element,若第一個 element 不符合則停止 take
predicate : ('T -> bool) -> list : 'T list -> 'T list
1 | [ 1 .. 10 ] |
List.toArray
將 list 轉成 array
list : 'T list -> 'T []
1 | [ 1; 2; 3 ] |
List.toSeq
將 list 轉成 sequence
list : 'T list -> seq<'T>
1 | [ 1; 2; 3 ] |
List.transpose
將 sequence 內的 list 加以 transpose
list : seq<'T list> -> 'T list list
1 | [[ 1; 2; 3]] |
List.truncate
回傳 list 最多 n 的 element
count : int -> list : 'T list -> 'T list
1 | [1; 2; 3] |
Q :
List.truncate()
與List.take()
有何差異?
當 n 大於 Length
時,List.truncate()
不會報錯,只是將整個 list 傳回;但 List.take()
拋出 InvalidOperationException
List.tryFind
找出 list 中符合 predicate function 條件的第一個 element
predicate : ('T -> bool) -> list : 'T list -> 'T option
1 | [ 1 .. 10 ] |
List.find()
與List.tryFind()
有何差異?
相同
- 都使用 predicate function 為搜尋條件
相異
List.find()
傳回'T
;而List.tryFind()
傳回'T option
若找不到資料,
List.find()
會拋出KeyNotFoundException
;但List.tryFind()
只會回傳None
實務上建議使用
List.tryFind()
取代List.find()
,較為安全
List.tryFindBack
從 list 尾部找出符合 predicate function 條件的第一個 element
predicate:('T -> bool) -> list : 'T list -> 'T option
1 | [ 1 .. 10 ] |
Q:
List.findBack()
與List.tryFindBack()
有何差異?
相同
- 都使用 predicate function 為搜尋條件
相異
List.findBack()
傳回'T
;而List.tryFindBack()
傳回'T option
若找不到資料,
List.findBack()
會拋出KeyNotFoundException
;但List.tryFindBack()
只會回傳None
實務上建議使用
List.tryFindBack()
取代List.findBack()
,較為安全
List.tryFindIndex
找出 list 中符合 predicate function 條件的第一 element 的 index
predicate : ('T -> bool) -> list : 'T list -> int option
1 | [ 1 .. 10 ] |
Q:
List.findIndex()
與List.tryFindIndex()
有何差異?
相同
- 都使用 predicate function 為搜尋條件
相異
List.findIndex()
傳回int
;而List.tryFindIndex()
傳回int option
若找不到資料,
List.findIndex()
會拋出KeyNotFoundException
;但List.tryFindIndex()
只會回傳None
實務上建議使用
List.tryFindIndex()
取代List.findIndex()
,較為安全
List.tryFindIndexBack
從 list 尾部找出符合 predicate function 條件的第一 element 的 index
predicate : ('T -> bool) -> list : 'T list -> int option
1 | [ 1 .. 10 ] |
Q:
List.findIndexBack()
與List.tryFindIndexBack()
有何差異?
相同
- 都使用 predicate function 為搜尋條件
相異
List.findIndexBack()
傳回int
;而List.tryFindIndexBack()
傳回int option
若找不到資料,
List.findIndexBack()
會拋出KeyNotFoundException
;但List.tryFindIndexBack()
只會回傳None
實務上建議使用
List.tryFindIndexBack()
取代List.findIndexBack()
,較為安全
List.tryHead
傳回 list 第一個 element,相當於 list 的
Head
property
list : 'T list -> 'T option
1 | [ 1; 2; 3 ] |
Q:
List.head()
與List.tryHead()
有何差異?
相同
- 都傳回 list 第一個 element
相異
List.head()
傳回'T
;而List.tryHead()
傳回'T option
若找不到資料,
List.head()
會拋出ArgumentException
;但List.tryHead()
只會回傳None
實務上建議使用
List.tryHead()
取代List.head()
,較為安全
List.tryItem
傳回 list 指定 index 的 element 值,相當於 list 的
Item
property
index : int -> list : 'T list -> 'T option
1 | [ 1; 2; 3 ] |
Q:
List.item()
與List.tryItem()
有何差異?
相同
- 都傳回 list 指定 index 的 element 值
相異
List.item()
傳回'T
;而List.tryItem()
傳回'T option
若找不到資料,
List.head()
會拋出ArgumentException
;但List.tryHead()
只會回傳None
實務上建議使用
List.tryItem()
取代List.item()
,較為安全
List.tryLast
傳回 list 最後一個 element
list : 'T list -> 'T option
1 | [ 1; 2; 3 ] |
Q:
List.last()
與List.tryLast()
有何差異?
相同
- 都傳回 list 最後一個 element 值
相異
List.last()
傳回'T
;而List.tryLast()
傳回'T option
若找不到資料,
List.last()
會拋出ArgumentException
;但List.tryLast()
只會回傳None
實務上建議使用
List.tryLast()
取代List.last()
,較為安全
List.tryPick
找出 list 中符合 chooser function 條件的第一個 element
chooser : ('T -> 'U option) -> list : 'T list -> 'U option
1 | let chooser elm = |
Q:
List.pick()
與List.tryPick()
有何差異?
相同
- 都使用 chooser function 為搜尋條件
相異
List.pick()
傳回'U
;而List.tryPick()
傳回'U option
若找不到資料,
List.pick()
會拋出KeyNotFoundException
;但List.tryPick()
只會回傳None
實務上建議使用
List.tryPick()
取代List.pick()
,較為安全
List.unfold
根據 generator function 建立 list,其中 generator function 可指定目前 state 與下一個 state
generator : ('State -> ('T * 'State) option) -> state : 'State -> 'T list
1 | let generator state = |
List.unzip
將所有 element 為 pair 的 list,分解成兩個 list
list : ('T1 * 'T2) list -> 'T1 list * 'T2 list
1 | [ (1, 4); (2, 5); (3, 6) ] |
List.unzip3
將所有 element 為 triple 的 list,分解成三個 list
list : ('T1 * 'T2 * 'T3) list -> 'T1 list * 'T2 list * 'T3 list
1 | [ (1, 4, 7); (2, 5, 8); (3, 6, 9) ] |
List.where
找出 list 中符合 predicate function 條件的所有 element
predicate : ('T -> bool) -> list : 'T list -> 'T list
1 | [ 1; 2; 3] |
List.windowed
依照 list 的 element 順序,依序取出 n 個 element 的 list
windowSize : int -> list : 'T list -> 'T list list
1 | [ 1 .. 5 ] |
List.zip
將兩個 list 合併成 element 為 pair 的 list
list1 : 'T1 list -> list2 : 'T2 list -> ('T1 * 'T2) list
1 | let list1 = [ 1; 2; 3 ] |
List.zip3
將三個 list 合併成 element 為 triple 的 list
list1 : 'T1 list -> list2 : 'T2 list -> list3 : 'T3 list -> ('T1 * 'T2 * 'T3) list
1 | let list1 = [ 1; 2; 3 ] |
Conclusion
- List module 所提供的 function 都必須非常熟練,因為這些都是常用的 Higher Order Function,算是 FP 的基本功