深入探討 List Module 所提供的 Function (G ~ P)

栏目: ASP.NET · 发布时间: 6年前

内容简介: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

MSDN , Collection.List Module (F#)


以上所述就是小编给大家介绍的《深入探討 List Module 所提供的 Function (G ~ P)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

千夫所指

千夫所指

乔恩·罗森 / 王岑卉 / 九州出版社 / 2016-10-1 / CNY 42.80

编辑推荐: 《乌合之众》是为了跪舔权贵?《普通心理学》实验存在重大漏洞?《引爆点》的理论都是瞎掰的?社交网络时代《1984》预言的“老大哥”是否已经变成事实? 《纽约时报》年度十佳书 《GQ》杂志年度十佳书 《卫报》年度十佳书 《泰晤士报》年度十佳书 《经济学人》年度重推! 黑天鹅年度重点图书! 《乌合之众》是为了迎合权贵?《普通心理学》实验存在重大......一起来看看 《千夫所指》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具