F# - 列表

在F#中,列表是一个有序的,不可变的相同类型的元素系列.它在某种程度上等同于链表数据结构.

F#模块, Microsoft.FSharp.Collections.List,在列表上有常见的操作.但是F#会自动导入该模块,并使每个F#应用程序都可以访问它.

创建和初始化列表

以下是创建列表的各种方法 :

  • 使用列表文字.

  • 使用缺点(::)运算符.

  • 使用 List.init 列表模块的方法.

  • 使用一些名为列表推导句法结构.

列表文字

在此方法中,您只需在方括号中指定以分号分隔的值序列.例如 :

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]


缺点(::)运算符

使用此方法,您可以通过预先添加或添加一些值使用::运算符将包含到现有列表中.例如 :

let list2 = 1::2::3::4::5::6::7::8::9::10::[];;


[]表示空列表.

列表初始化方法

List模块的List.init方法通常用于创建列表.此方法的类型为 :

val init : int -> (int -> 'T) -> 'T list


第一个参数是新列表的所需长度,第二个参数是初始化函数,它在列表中生成项目./p>

例如,

let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))


这里,索引函数生成列表.

列表理解

列表推导是用于生成列表的特殊语法结构.

F#list comprehension syntax有两种形式 : 范围和生成器.

范围有结构和减号; [start .. end]和[start .. step .. end]

例如,

let list3 = [1 .. 10]


生成器具有构造和减号; [for x in collection do ... yield expr]

例如,

let list6 = [ for a in 1 .. 10 do yield (a * a) ]


因为 yield 关键字将单个值推入列表,关键字 yield!,将一组值推送到列表中.

以下函数演示了上述方法 :

示例

(* using list literals *)
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1

(*using cons operator *)
let list2 = 1 :: 2 :: 3 :: []
printfn "The list: %A" list2

(* using range constructs*)
let list3 = [1 .. 10]
printfn "The list: %A" list3

(* using range constructs *)
let list4 = ['a' .. 'm']
printfn "The list: %A" list4

(* using init method *)
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
printfn "The list: %A" list5

(* using yield operator *)
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
printfn "The list: %A" list6

(* using yield operator *)
let list7 = [ for a in 1 .. 100 do if a % 3 = 0 && a % 5 = 0 then yield a]
printfn "The list: %A" list7

(* using yield! operator *)
let list8 = [for a in 1 .. 3 do yield! [ a .. a + 3 ] ]
printfn "The list: %A" list8


编译并执行程序时,它会产生以下输出 :

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: [1; 2; 3]
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm']
The list: [(0, 0, 0); (1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64)]
The list: [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
The list: [15; 30; 45; 60; 75; 90]
The list: [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6]


列表数据类型的属性

下表显示了列表数据类型的各种属性 :

PropertyType描述
Head'T第一个元素.
Empty' T list一个静态属性,它返回一个相应类型的空列表.
IsEmptybool true 如果列表没有元素.
Item'T指定索引处的元素(零基于).
Lengthint元素数量.
Tail'T list没有第一个元素的列表.

以下示例显示了这些属性的使用 :

示例

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]

// Use of Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))


编译并执行程序时,它会产生以下输出 :

list1.IsEmpty is false
list1.Length is 8
list1.Head is 2
list1.Tail.Head is 4
list1.Tail.Tail.Head is 6
list1.Item(1) is 4


列表中的基本运算符

下表显示了列表数据类型&minus的基本操作;

Value描述
append :'T list →  'T list →  'T list返回一个新列表,其中包含第一个列表的元素,后跟第二个元素.
average:'T list →  ^ T返回列表中元素的平均值.
averageBy :('T →  ^ U) →  'T list →  ^ U返回通过将函数应用于列表的每个元素而生成的元素的平均值.
choose :('T → 'U选项) →  'T list →  'U list将给定的函数应用于列表的每个元素.返回由函数返回的每个元素的结果组成的列表一些.
collect :('T → 'U list) →  'T list →  'U list对于列表的每个元素,应用给定的函数.连接所有结果并返回组合列表.
concat:seq<'T list> &RARR; 'T list返回一个新列表,按顺序包含每个列表的元素.
empty:'T list返回给定类型的空列表.
exists :('T →  bool) →  'T list →  bool测试列表中的任何元素是否满足给定的谓词.
exists2:('T1 → 'T2 →  bool) →  'T1 list →  'T2 list →  bool测试列表的任何一对相应元素是否满足给定的谓词.
filter :('T →  bool) →  'T list →  'T list返回一个新集合,其中只包含给定谓词返回的集合元素 true .
find:('T →  bool) →  'T list →  'T返回给定函数返回的第一个元素 true .
findIndex:('T →  bool) →  'T list →  int返回列表中第一个满足给定谓词的元素的索引.
fold:('State → 'T → 'State) →  '州 →  'T list →  'State将一个函数应用于集合的每个元素,通过计算线程化一个累加器参数.此函数接受第二个参数,并将函数应用于它和列表的第一个元素.然后,它将此结果与第二个元素一起传递给函数,依此类推.最后,它返回最终结果.如果输入函数是f并且元素是i0 ... iN,则此函数计算f(...(fs i0)i1 ...)iN.
fold2:('State → 'T1 → 'T2 → 'State) →  '州 →  'T1 list →  'T2 list →  'State将函数应用于两个集合的相应元素,通过计算线程化累加器参数.集合必须具有相同的大小.如果输入函数是f并且元素是i0 ... iN和j0 ... jN,则此函数计算f(...(fs i0 j0)...)iN jN.
foldBack:('T → 'State → 'State) →  'T list →  '州 →  'State将一个函数应用于集合的每个元素,通过计算线程化一个累加器参数.如果输入函数是f并且元素是i0 ... iN则计算f i0(...(f iN s)).
foldBack2:('T1 → 'T2 → 'State → 'State) →  'T1 list →  'T2 list →  '州 →  'State将函数应用于两个集合的相应元素,通过计算线程化累加器参数.集合必须具有相同的大小.如果输入函数是f并且元素是i0 ... iN和j0 ... jN,则此函数计算f i0 j0(...(f iN jN s)).
forall:('T →  bool) →  'T list →  bool测试集合的所有元素是否满足给定的谓词.
forall2:('T1 → 'T2 →  bool) →  'T1 list →  'T2 list →  bool测试集合的所有相应元素是否成对满足给定的谓词.
head:'T list →  'T返回列表的第一个元素.
init:int &RARR; (int → 'T) →  'T list通过在每个索引上调用给定的生成器来创建一个列表.
isEmpty:'T list →  bool如果列表中不包含任何元素,则返回 true ,否则返回 false .
iter:('T →  unit) →  'T list →  unit将给定的函数应用于集合的每个元素.
iter2 :('T1 → 'T2 →  unit) →  'T1 list →  'T2 list →  unit同时将给定函数应用于两个集合.集合必须具有相同的大小.
iteri:(int → 'T →  unit) →  'T list →  unit将给定函数应用于集合的每个元素.传递给函数的整数表示元素的索引.
iteri2:(int → 'T1 → 'T2  →  unit) →  'T1 list →  'T2 list →  unit同时将给定函数应用于两个集合.集合必须具有相同的大小.传递给函数的整数表示元素的索引.
length:'T list →  int返回列表的长度.
map:('T  → 'U) →  'T list →  'U list创建一个新集合,其元素是将给定函数应用于集合的每个元素的结果.
map2:('T1 → 'T2 → 'U) →  'T1 list →  'T2 list →  'U list创建一个新集合,其元素是将给定函数成对应用于两个集合的相应元素的结果.
map3:('T1 → 'T2 → 'T3 → 'U) →  'T1 list →  'T2 list →  'T3 list →  'U list创建一个新集合,其元素是将给定函数同时应用于三个集合的相应元素的结果.
mapi:(int → 'T → 'U) →  'T list →  'U list创建一个新集合,其元素是将给定函数应用于集合的每个元素的结果.传递给函数的整数索引表示正在转换的元素的索引(从0开始).
mapi2:(int&rarr ;'T1 → 'T2 → 'U) →  'T1 list →  'T2 list →  'U list与List.mapi类似,但是从两个相等长度的列表中映射相应的元素.
max:'T list →  'T返回列表中所有元素中最大的元素,使用Operators.max进行比较.
maxBy:('T → 'U) →  'T list →  'T返回列表中所有元素中最大的元素,通过在函数结果上使用Operators.max进行比较.
min:'T list →  'T返回列表中所有元素的最低值,使用Operators.min进行比较.
minBy:('T → 'U) →  'T list →  'T返回列表中所有元素的最低值,通过在函数结果上使用Operators.min进行比较
nth:'T list →  int →  'T列入索引.第一个元素的索引为0.
ofArray:'T [] →  'T list从给定数组创建一个列表.
ofSeq : seq<'T> →'T list从给定的可枚举对象创建一个新列表.
partition :('T →  bool) →  'T list *'T list将集合拆分为两个集合,其中包含给定谓词返回的元素 true false 分别.
permute:(int →  int) →  'T list →  'T list返回一个列表,其中所有元素都根据指定的排列进行置换.
pick :('T → 'Uoption) →  'T list →  'U将给定的函数应用于连续的元素,返回第一个结果,其中函数返回 Some 表示某个值.
reduce:('T → 'T → 'T) →  'T list →  'T将一个函数应用于集合的每个元素,通过计算线程化一个累加器参数.此函数将指定的函数应用于列表的前两个元素.然后它将此结果与第三个元素一起传递给函数,依此类推.最后,它返回最终结果.如果输入函数是f并且元素是i0 ... iN,则此函数计算f(...(f i0 i1)i2 ...)iN.
reduceBack:('T → 'T → 'T) →  'T list →  'T将一个函数应用于集合的每个元素,通过计算线程化一个累加器参数.如果输入函数是f并且元素是i0 ... iN,则此函数计算f i0(...(f iN-1 iN)).
replicate :(int → 'T → 'T list)通过在每个索引上调用给定的生成器来创建列表.
rev:'T list →  'T list以相反的顺序返回一个包含元素的新列表.
scan :('State → 'T → 'State) →  'State  →  'T list →  'State list将一个函数应用于集合的每个元素,通过计算线程化一个累加器参数.此函数接受第二个参数,并将指定的函数应用于它和列表的第一个元素.然后,它将此结果与第二个元素一起传递给函数,依此类推.最后,它返回中间结果列表和最终结果.
scanBack:('T → 'State→'State  →  'T list →  'State →  'State list与foldBack类似,但同时返回中间和最终结果
sort :'T list →  'T list使用Operators.compare对给定列表进行排序.
sortBy :('T → 'Key) →  'T list →  'T list使用给定投影给出的键对给定列表进行排序.使用Operators.compare比较密钥.
sortWith:('T → 'T →  int) →  'T list →  'T list使用给定的比较函数对给定列表进行排序.
sum :^ T list →  ^ T返回列表中元素的总和.
sumBy :('T →  ^ U) →  'T list →  ^ U返回通过将函数应用于列表的每个元素而生成的结果的总和.
tail:'T list →  'T list返回没有第一个元素的输入列表.
toArray :'T list →  'T []从给定列表创建一个数组.
toSeq :'T list →  seq<'T>将给定列表视为序列.
tryFind:('T →  bool) →  'T list →  'Toption返回给定函数返回 true 的第一个元素.如果不存在这样的元素,则返回.
tryFindIndex:('T →  bool) &RARR; 'T list →  intoption返回列表中满足给定谓词的第一个元素的索引.如果不存在这样的元素,则返回.
tryPick:('T → 'Uoption) →  'T list →  'Uoption将给定函数应用于连续元素,返回第一个结果,其中函数返回 Some 表示某个值.如果不存在这样的元素,则返回.
unzip :('T1 *'T2 )list →  'T1 list *'T2 list将对列表拆分为两个列表.
unzip3:('T1 *'T2 *'T3)list →  'T1 list *'T2 list *'T3 list将三元组列表拆分为三个列表.
zip:'T1 list →  'T2 list →  ('T1 *'T2)list将两个列表组合成一对列表.这两个列表的长度必须相等.
zip3:'T1 list →  'T2 list →  'T3 list →  ('T1 *'T2 *'T3)list将三个列表组合成三元组列表.列表必须具有相同的长度.

以下示例演示了上述功能的使用和减号;

示例1

此程序显示递归反转列表 :

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1

let reverse lt =
   let rec loop acc = function
      | [] -> acc
      | hd :: tl -> loop (hd :: acc) tl
   loop [] lt

printfn "The reversed list: %A" (reverse list1)


编译并执行程序时,它会产生以下输出 :

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]


但是,您可以将模块的 rev 功能用于相同目的 :

alet list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)


编译并执行程序时,它会产生以下输出 :

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]


示例2

此程序显示使用 List.filter 方法:

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.filter (fun x -> x % 2 = 0);;
printfn "The Filtered list: %A" list2


编译并执行程序时,它会产生以下输出 :

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]


示例3

List.map 方法从一个列表中映射列表输入到另一个 :

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.map (fun x -> (x * x).ToString());;
printfn "The Mapped list: %A" list2


编译并执行程序时,它会产生以下输出 :

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Mapped list: ["1"; "4"; "9"; "16"; "25"; "36"; "49"; "64"; "81"; "100"]


示例4

List.append 方法和@运算符将一个列表附加到另一个 :

let list1 = [1; 2; 3; 4; 5 ]
let list2 = [6; 7; 8; 9; 10]
let list3 = List.append list1 list2

printfn "The first list: %A" list1
printfn "The second list: %A" list2
printfn "The appened list: %A" list3

let lt1 = ['a'; 'b';'c' ]
let lt2 = ['e'; 'f';'g' ]
let lt3 = lt1 @ lt2

printfn "The first list: %A" lt1
printfn "The second list: %A" lt2
printfn "The appened list: %A" lt3


编译并执行程序时,它会产生以下输出 :

The first list: [1; 2; 3; 4; 5]
The second list: [6; 7; 8; 9; 10]
The appened list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The first list: ['a'; 'b'; 'c']
The second list: ['e'; 'f'; 'g']
The appened list: ['a'; 'b'; 'c'; 'e'; 'f'; 'g']


示例5

List.sort 方法对列表进行排序. List.sum 方法给出了列表中元素的总和, List.average 方法给出了列表中元素的平均值 :

let list1 = [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
printfn "The list: %A" list1

let list2 = List.sort list1
printfn "The sorted list: %A" list2

let s = List.sum list1
let avg = List.average list1
printfn "The sum: %f" s
printfn "The average: %f" avg


编译并执行程序时,它会产生以下输出 :

The list: [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
The sorted list: [-10.0; -4.5; 0.0; 2.0; 8.0; 9.0; 11.2]
The sum: 15.700000
The average: 2.242857


"折叠"操作将函数应用于列表中的每个元素,在累加器变量中聚合函数的结果,并作为折叠操作的结果返回累加器.

示例6

List.fold 方法从左到右为每个元素应用一个函数,而 List.foldBack 从右到左对每个元素应用一个函数.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 10 ] (sumList [ 1 .. 10 ])


编译并执行程序时,它会产生以下输出 :

Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.