内容简介:F# 的 List module 提供眾多本文探討英文字母 G ~ P 開頭的 function。macOS High Sierra 10.13.3
F# 的 List module 提供眾多 List
常用的 Higher Order Function,要能發揮 FP 的威力,首先必須能活用內建 function。
本文探討英文字母 G ~ P 開頭的 function。
Version
macOS High Sierra 10.13.3
.NET Core SDK 2.1.101
JetBrains Rider 2017.3.1
F# 4.1
List.head
傳回 list 第一個 element,相當於 list 的 Head
property
list : 'T list -> 'T
[ 1; 2; 3 ] |> List.head |> printf "%d" // 1
List.indexed
將 element 的 key 與 value 封裝成 tuple,以 list 回傳
list : 'T list -> (int * 'T) list
[ 1; 2; 3 ] |> List.indexed |> printf "%A" // [(0, 1); (1, 2); (2, 3)]
List.init
根據 index 值建立新的 list
int -> initializer : (int -> 'T) -> 'T list
List.init 10 (fun idx -> idx * 2) |> printf "%A" // [0; 2; 4; 6; 8; 10; 12; 14; 16; 18]
List.isEmpty
判斷 list 是否為空,相當於 list 的 IsEmpty
property
list : 'T list -> bool
[] |> List.isEmpty |> printf "%b" // true
List.item
傳回指定 index 的 element 值,相當於 list 的 Item
property
index : int -> list : 'T list -> 'T
[ 1; 2; 3 ] |> List.item 2 |> printf "%d" // 3
List.iter
對每個 element 執行回傳值為 unit
的 action function
action : ('T -> unit) -> list : 'T list -> unit
[ 1; 2; 3 ] |> List.iter (printf "%A ") // 1 2 3
List.iter2
同時對兩個 list 的每個 element 執行回傳值為 unit
的 action function
action : ('T1 -> 'T2 -> unit) -> list1 : 'T1 list -> list2 : 'T2 list -> unit
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] let action elm1 elm2 = printf "%d " (elm1 + elm2) List.iter2 action list1 list2 // 5 7 9
List.iteri
對每個 element 執行回傳值為 unit
的 action function,但會將 index 也傳入 action function
action : (int -> 'T -> unit) -> list : 'T list -> unit
[ 1 .. 3 ] |> List.iteri (fun idx elm -> printfn "%d : %d" idx elm) // 0 : 1 // 1 : 2 // 2 : 3
List.iteri2
同時對兩個 list 的每個 element 執行回傳值為 unit
的 action function,但會將 index 也傳入 action function
action : (int -> 'T1 -> 'T2 -> unit) -> list1 : 'T1 list -> list2 : 'T2 list -> unit
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] let action idx elm1 elm2 = printfn "%d : %d" idx (elm1 + elm2) List.iteri2 action list1 list2 // 0 : 5 // 1 : 7 // 2 : 9
List.last
傳回 list 最後一個 element
list : 'T list -> 'T
[ 1; 2; 3 ] |> List.last |> printf "%d" // 3
List.length
傳回 list 的 element 個數,相當於 list 的 Length
property
list: 'T list -> int
[ 1; 2; 3 ] |> List.length |> printf "%d" // 3
List.map
將 list 的每個 element 根據 mapping function 轉換成另外一個 value 的 list
mapping : ('T -> 'U) -> list : 'T list -> 'U list
[ 1; 2; 3 ] |> List.map (fun elm -> elm * elm) |> printf "%A" // [1; 4; 9]
若經過 mapping function 後 element 個數不一樣,請用 List.collect()
List.map2
將兩個 list 的每個 element 根據 mapping function 轉換成另外一個 value 的 list
mapping : ('T1 -> 'T2 -> 'U) -> list1 : 'T1 list -> list2 : 'T2 list -> 'U list
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] List.map2 (fun elem1 elem2 -> elem1 + elem2) list1 list2 |> printf "%A" // [5; 7; 9]
List.map3
將三個 list 的每個 element 根據 mapping function 轉換成另外一個 value 的 list
mapping : ('T1 -> 'T2 -> 'T3 -> 'U) -> list1 : 'T1 list -> list2 : 'T2 list -> list3 : 'T3 list -> 'U list
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] let list3 = [ 7; 8; 9 ] List.map3 (fun elm1 elm2 elm3 -> elm1 + elm2 + elm3) list1 list2 list3 |> printf "%A" // [12; 15; 18]
List.mapFold
相當於 List.map()
+ List.fold()
合體,回傳為 tuple。
mapping : ('State -> 'T -> 'Result * 'State) -> state : 'State -> list : 'T list -> 'Result list * 'State
[ 1; 2; 3 ] |> List.mapFold (fun acc elm -> (elm * elm , acc + elm * elm)) 0 |> printf "%A" // ([1; 4; 9], 14)
mapping funciton 中,回傳的是 tuple。
-
第 1 個 element 為
List.map()
的結果 -
第 2 個 element 為
List.fold()
的結果
List.mapFoldBack
相當於 List.map()
+ List.fold()
合體,回傳為 tuple,但從 list 的尾部開始,signature 的順序也不一樣
mapping : ('T -> 'State -> 'Result * 'State) -> list : 'T list -> state : 'State -> 'Result * 'State
let list1 = [ 1; 2; 3 ] List.mapFoldBack (fun elm acc -> (elm * elm , acc + elm * elm)) list1 0 |> printf "%A" // ([1; 4; 9], 14)
List.mapi
對 list 的每個 element 根據 mapping function 轉換成另外一個 value 的 list,但會將 index 也傳入 mapping function
mapping : (int -> 'T -> 'U) -> list : 'T list -> 'U list
[ 1; 2; 3 ] |> List.mapi (fun idx elm -> idx * elm) |> printf "%A" // [0; 2; 6]
List.mapi2
同時對兩個 list 的每個 element 根據 mapping function 轉換成另外一個 value 的 list,但會將 index 也傳入 mapping function
let list1 = [ 1; 2; 3 ] let list2 = [ 4; 5; 6 ] let mapping idx elm1 elm2 = idx + elm1 + elm2 List.mapi2 mapping list1 list2 |> printf "%A" // [5; 8; 11]
List.max
傳回 list 內最大的值
list : 'T list -> 'T
[ 1; 2; 3 ] |> List.max |> printf "%d" // 3
List.maxBy
傳回 list 內的最大值,但所比較的是經過 projection function 轉換過的值
project : ('T -> 'U) -> list : 'T list -> 'T
[ 1; 2; 3 ] |> List.maxBy (fun elm -> 1 - elm) |> printf "%d" // 1
[1; 2; 3]
經過 projection function 後為 [0; -1; -2]
,所以最大值為 0
,但 List.maxBy()
回傳的是原 list 的值,所以為 1
。
Projection function 的值只是比較用,不是回傳用
List.min
傳回 list 內最小的值
list : 'T list -> 'T
[ 1; 2; 3 ] |> List.min |> printf "%d" // 1
List.minBy
傳回 list 內的最小值,但所比較的是經過 projection function 轉換過的值
project : ('T -> 'U) -> list : 'T list -> 'T
[ 1; 2; 3 ] |> List.minBy (fun elm -> 1 - elm) |> printf "%d" // 3
[1; 2; 3]
經過 projection function 後為 [0; -1; -2]
,所以最小值為 0
,但 List.minBy()
回傳的是原 list 的值,所以為 3
。
Projection function 的值只是比較用,不是回傳用
List.ofArray
由 array 轉成 list
array : 'T [] -> 'T list
[| 1; 2; 3 |] |> List.ofArray |> printf "%A" // [1; 2; 3]
List.ofSeq
由 sequence 轉成 list
source : seq<'T> -> 'T list
seq { 1 .. 5 } |> List.ofSeq |> printf "%A" // [1; 2; 3; 4; 5]
List.pairWise
根據 list 順序,回傳兩兩成為 tuple 的 list
list : 'T list -> ('T * 'T) list
[ 1; 2; 3; 4 ] |> List.pairwise |> printf "%A" //[(1, 2); (2, 3); (3, 4)]
List.partition
將 list 根據 predicate function 拆成兩個 list,同時放在一個 tuple 中傳回
predicate : ('T -> bool) -> list : 'T list -> 'T list * 'T list
[ 1 .. 10 ] |> List.partition (fun elm -> elm % 2 = 0) |> printf "%A" // ([2; 4; 6; 8; 10], [1; 3; 5; 7; 9])
List.permute
List 重新根據 indexMap function 的規則,重新調整 element 順序
indexMap : (int -> int) -> list : 'T list -> 'T list
[ 1; 2; 3 ] |> List.permute (fun idx -> (idx + 1) % 3) |> printf "%A" // [3; 1; 2]
List.pick
找出符合 chooser function 條件的第一個 element
chooser : ('T -> 'U option) -> list : 'T list -> -> 'U
let chooser elm = match elm with | elm when elm % 2 = 0 -> Some elm | _ -> None [ 1; 2; 3 ] |> List.pick chooser |> printf "%A" // 2
若找不到 element,會拋出 KeyNotFoundException : An index satisfying the predicate was not found in the collection.
Q: List.find()
與 List.pick()
有何差異?
相同
-
都用來找資料
-
找不到資料都會拋出
KeyNotFoundException
相異
-
List.find()
的 predicate function 為'T -> bool
-
List.pick()
的 chooser function 為'T -> 'U option
若 fuction 回傳為 option
,則適合用 List.pick()
,否則使用 List.find()
Conclusion
- List module 所提供的 function 都必須非常熟練,因為這些都是常用的 Higher Order Function,算是 FP 的基本功
Reference
以上所述就是小编给大家介绍的《深入探討 List Module 所提供的 Function (G ~ P)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 深入探討 F# List Module 所提供的 Function (Q ~ Z)
- 深入探討 List Module 所提供的 Function Part I (A ~ F)
- 能快速提供一个子环境吗?
- 提供一个排查性能问题的思路
- 创新中关村报道称 Cocos 开发者沙龙为开发者、技术提供者等提供了交流合作平台
- C/C++ 提供 Python 接口
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。