内容简介:F# 的 List module 提供眾多本文先探討英文字母 Q ~ Z 開頭的 function。macOS High Sierra 10.13.3
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
JetBrains Rider 2017.3.1
F# 4.1
List.reduce
將 list 中每個 element 的值經過 reduction function 累加
reduction : ('T -> 'T -> 'T) -> list : 'T list -> 'T
[ 1; 2; 3 ] |> List.reduce (fun acc elm -> acc + elm) |> printf "%A" // 6
Q : List.fold()
與 List.reduce()
有何差異?
[ 1; 2; 3 ] |> List.fold (fun elm acc -> acc + elm) 0 |> printf "%A" // 6
相同
-
都是
累加
相異
-
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; 2; 3 ] |> List.reduceBack (fun elm acc -> acc + elm) |> printf "%A" // 6
List.replicate
以相同 element 建立 list
count : int -> initial : 'T -> 'T list
List.replicate 3 0 |> printf "%A" // [0; 0; 0]
List.rev
將 list 反過來表示
list : 'T list -> 'T list
[ 1; 2; 3 ] |> List.rev |> printf "%A" // [3; 2; 1]
List.scan
類似 List.fold()
與 List.reduce()
對 list 進行累加,但會將計算過程保留在新 list 的 element
folder : ('State -> 'T -> 'State) -> state : 'State -> list : 'T list -> 'State list
[ 1; 2; 3 ] |> List.scan (fun acc elm -> acc + elm) 0 |> printf "%A" // [0; 1; 3; 6]
List.scanBack
同 List.scan()
,但從 list 尾部開始累加,並將最後結果先顯示
folder : ('T -> 'State -> 'State) -> list : 'T list -> state : 'State -> 'State list
let list1 = [ 1; 2; 3 ] List.scanBack (fun elm acc -> acc + elm) list1 0 |> printf "%A" // [6; 5; 3; 0]
List.singleton
將整個 list 成為新 list 的第一個 element
value : 'T -> 'T list
[ 1; 2; 3 ] |>List.singleton |> printf "%A" // [[1; 2; 3]]
List.skip
忽略前 n 個 element 並傳回新 list
count : int -> list : 'T list -> 'T list
[ 1 .. 10 ] |>List.skip 5 |> printf "%A" // [6; 7; 8; 9; 10]
List.skipWhile
忽略前 n 個符合 predicate function 的 element,若第一個 element 不符合則停止 skip
predicate : ('T -> bool) -> list : 'T list -> 'T list
[ 1 .. 10 ] |>List.skipWhile (fun elm -> elm < 5) |> printf "%A" // [5; 6; 7; 8; 9; 10]
List.sort
將 list 排序 (由小到大)
list : 'T list -> 'T list
[ 3; 2; 1 ] |>List.sort |> printf "%A" // [1; 2; 3]
List.sortDescending
將 list 排序 (由大到小)
list : 'T list -> 'T list
[ 1; 2; 3 ] |>List.sortDescending |> printf "%A" // [3; 2; 1]
List.sortBy
將 list 的 element 透過 projection function 轉換過,再根據 key 排序 (由小到大)
projection : ('T -> 'Key) -> list : 'T list -> 'T list
[ 3; 2; 1 ] |>List.sortBy (fun elm -> elm) |> printf "%A" // [1; 2; 3]
List.sortByDescending
將 list 的 element 透過 projection function 轉換過,再根據 key 排序 (由大到小)
projection : ('T -> 'Key) -> list : 'T list -> 'T list
[ 1; 2; 3 ] |>List.sortByDescending (fun elm -> elm) |> printf "%A" // [3; 2; 1]
List.sortWith
將 list 的 element 透過 comparer function 排序
comparer : ('T -> 'T -> int) -> list : 'T list -> 'T list
[ 3; 2; 1 ] |>List.sortWith (fun elm1 elm2 -> elm1 - elm2) |> printf "%A" // [1; 2; 3]
List.splitAt
將 list 根據指定 index 分成兩個 list
index : int -> list : 'T list -> 'T list * 'T list
[ 1 .. 10 ] |>List.splitAt 5 |> printf "%A" // ([1; 2; 3; 4; 5], [6; 7; 8; 9; 10])
List.splitInto
將 list 分成指定 chunk 數
count : int -> list : 'T list -> 'T list list
[ 1 .. 10 ] |>List.splitInto 3 |> printf "%A" // [[1; 2; 3; 4]; [5; 6; 7]; [8; 9; 10]]
List.sum
將 list 中所有 element 相加
list : 'T list -> 'T
[ 1; 2; 3 ] |>List.sum |> printf "%A" // 6
List.sumBy
將 list 先將過 projection function 運算後再相加,相當於 List.map()
+ List.sum()
projection : ('T -> 'U) -> list : 'T list -> 'U
[ 1; 2; 3 ] |>List.sumBy (fun elm -> elm * elm) |> printf "%A" // 14
相當於
[ 1; 2; 3 ] |> List.map (fun elm -> elm * elm) |> List.sum |> printf "%A" // 14
List.tail
將 list 除了第 1 個 element 外,剩下的 list 傳回,相當於 list 的 Tail
property
list : 'T list -> 'T list
[ 1; 2; 3 ] |>List.tail |> printf "%A" // [2; 3]
List.take
回傳 list 前 n 個 element
count : int -> list : 'T list -> 'T list
[ 1 .. 10 ] |>List.take 3 |> printf "%A" // [1; 2; 3]
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 .. 10 ] |>List.takeWhile (fun elm -> elm < 5) |> printf "%A" // [1; 2; 3; 4]
List.toArray
將 list 轉成 array
list : 'T list -> 'T []
[ 1; 2; 3 ] |>List.toArray |> printf "%A" // [|1; 2; 3|]
List.toSeq
將 list 轉成 sequence
list : 'T list -> seq<'T>
[ 1; 2; 3 ] |>List.toSeq |> printf "%A" // [1; 2; 3]
List.transpose
將 sequence 內的 list 加以 transpose
list : seq<'T list> -> 'T list list
[[ 1; 2; 3]] |>List.transpose |> printf "%A" // [[1]; [2]; [3]]
List.truncate
回傳 list 最多 n 的 element
count : int -> list : 'T list -> 'T list
[1; 2; 3] |>List.truncate 6 |> printf "%A" // [1; 2]
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 .. 10 ] |> List.tryFind (fun elm -> elm % 2 = 0) |> printf "%A" // Some 2
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 .. 10 ] |> List.tryFindBack (fun elm -> elm % 2 = 0) |> printf "%A" // Some 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 .. 10 ] |> List.tryFindIndex (fun elm -> elm % 2 = 0) |> printf "%A" // Some 1
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 .. 10 ] |> List.tryFindIndexBack (fun elm -> elm % 2 = 0) |> printf "%A" // Some 9
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; 2; 3 ] |> List.tryHead |> printf "%A" // Some 1
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; 2; 3 ] |> List.tryItem 2 |> printf "%A" // Some 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; 2; 3 ] |> List.tryLast |> printf "%A" // Some 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
let chooser elm = match elm with | elm when elm % 2 = 0 -> Some elm | _ -> None [ 1; 2; 3 ] |> List.tryPick chooser |> printf "%A" // Some 2
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
let generator state = match state with |_ when state < 10 -> Some(state, state + 1) |_ -> None List.unfold generator 0 |> printf "%A" // [0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
List.unzip
將所有 element 為 pair 的 list,分解成兩個 list
list : ('T1 * 'T2) list -> 'T1 list * 'T2 list
[ (1, 4); (2, 5); (3, 6) ] |> List.unzip |> printf "%A" // ([1; 2; 3], [4; 5; 6])
List.unzip3
將所有 element 為 triple 的 list,分解成三個 list
list : ('T1 * 'T2 * 'T3) list -> 'T1 list * 'T2 list * 'T3 list
[ (1, 4, 7); (2, 5, 8); (3, 6, 9) ] |> List.unzip3 |> printf "%A" // ([1; 2; 3], [4; 5; 6], [7; 8; 9])
List.where
找出 list 中符合 predicate function 條件的所有 element
predicate : ('T -> bool) -> list : 'T list -> 'T list
[ 1; 2; 3] |> List.where (fun elm -> elm % 2 = 1) |> printf "%A" // [1; 3]
List.windowed
依照 list 的 element 順序,依序取出 n 個 element 的 list
windowSize : int -> list : 'T list -> 'T list list
[ 1 .. 5 ] |> List.windowed 3 |> printf "%A" // [[1; 2; 3]; [2; 3; 4]; [3; 4; 5]]
List.zip
將兩個 list 合併成 element 為 pair 的 list
list1 : 'T1 list -> list2 : 'T2 list -> ('T1 * 'T2) list
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] List.zip list1 list2 |> printf "%A" // [(1, 4); (2, 5); (3, 6)]
List.zip3
將三個 list 合併成 element 為 triple 的 list
list1 : 'T1 list -> list2 : 'T2 list -> list3 : 'T3 list -> ('T1 * 'T2 * 'T3) list
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] let list3 = [ 7; 8; 9 ] List.zip3 list1 list2 list3 |> printf "%A" // [(1, 4, 7); (2, 5, 8); (3, 6, 9)]
Conclusion
- List module 所提供的 function 都必須非常熟練,因為這些都是常用的 Higher Order Function,算是 FP 的基本功
Reference
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 深入探討 List Module 所提供的 Function (G ~ P)
- 深入探討 List Module 所提供的 Function Part I (A ~ F)
- 能快速提供一个子环境吗?
- 提供一个排查性能问题的思路
- 创新中关村报道称 Cocos 开发者沙龙为开发者、技术提供者等提供了交流合作平台
- C/C++ 提供 Python 接口
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。