F# - 序列

序列,如列表也表示有序的值集合.但是,在需要时计算序列或序列表达式中的元素.它们不是一次计算的,因此它们用于表示无限数据结构.

定义序列

使用以下定义序列语法和减号;

seq { expr }


例如,

let seq1 = seq { 1 .. 10 }


创建序列和序列表达式

与列表类似,您可以使用范围和理解来创建序列.

序列表达式是您可以编写用于创建序列的表达式.这些可以完成和减去;

  • 通过指定范围.

  • 通过指定范围增量或减量.

  • 使用 yield 关键字生成成为序列一部分的值.

  • 使用 → 运算符.

以下示例演示了概念 :

示例1

(* Sequences *)
let seq1 = seq { 1 .. 10 }

(* ascending order and increment*)
printfn "The Sequence: %A" seq1
let seq2 = seq { 1 .. 5 .. 50 }

(* descending order and decrement*)
printfn "The Sequence: %A" seq2

let seq3 = seq {50 .. -5 .. 0}
printfn "The Sequence: %A" seq3

(* using yield *)
let seq4 = seq { for a in 1 .. 10 do yield a, a*a, a*a*a }
printfn "The Sequence: %A" seq4


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

The Sequence: seq [1; 2; 3; 4; ...]
The Sequence: seq [1; 6; 11; 16; ...]
The Sequence: seq [50; 45; 40; 35; ...]
The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]


示例2

以下程序打印从1到50的素数;

(* Recursive isprime function. *)
let isprime n =
   let rec check i =
      i > n/2 || (n % i <> 0 && check (i + 1))
   check 2

let primeIn50 = seq { for n in 1..50 do if isprime n then yield n }
for x in primeIn50 do
   printfn "%d" x


编译并执行程序时,会产生以下结果:输出&减去;

1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47


序列上的基本操作

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

cache : seq<'T> &rarr; seq<'T>
描述
append : seq<'T> &rarr; seq<'T> &rarr; seq<'T>
将两个给定的枚举包装为单个连接枚举.
average : seq<^T> &rarr; ^T返回序列中元素的平均值.
averageBy : ('T &rarr; ^U) &rarr; seq<'T> &rarr; ^U返回通过将函数应用于序列的每个元素而生成的结果的平均值.
返回与输入序列的缓存版本对应的序列.
cast : IEnumerable &rarr; seq<'T>包装松散类型的系统.集合序列作为类型化序列.
choose : ('T &rarr; 'U option) &rarr; seq<'T> &rarr; seq<'U>将给定函数应用于列表的每个元素.返回由函数返回的每个元素的结果组成的列表一些.
collect : ('T &rarr; 'Collection) &rarr; seq<'T> &rarr; seq<'U>将给定函数应用于序列的每个元素并连接所有结果.
compareWith : ('T &rarr; 'T &rarr; int) &rarr; seq<'T> &rarr; seq<'T> &rarr; int使用给定的比较函数逐个元素地比较两个序列.
concat : seq<'Collection> &rarr; seq<'T>将给定的枚举枚举组合为单个连接枚举.
countBy : ('T &rarr; 'Key) &rarr; seq<'T> &rarr; seq<'Key * int>将一个密钥生成函数应用于序列的每个元素,并返回一个序列,产生唯一键及其在原始序列中的出现次数.
delay : (unit &rarr; seq<'T>) &rarr; seq<'T>返回根据给定的序列延迟规范构建的序列.
distinct : seq<'T> &rarr; seq<'T>根据条目上的通用散列和相等比较,返回不包含重复条目的序列.如果一个元素在序列中多次出现,那么后面的事件将被丢弃.
distinctBy : ('T &rarr; 'Key) &rarr; seq<'T> &rarr; seq<'T>根据给定密钥生成函数返回的密钥的通用哈希和相等比较,返回不包含重复条目的序列.如果一个元素在序列中多次出现,则后面的事件将被丢弃.
empty:seq<'T>创建一个空序列.
exactlyOne : seq<'T> &rarr; 'T返回序列中唯一的元素.
exists : ('T &rarr; bool) &rarr; seq<'T> &rarr; bool测试序列中的任何元素是否满足给定的谓词.
exists2 : ('T1 &rarr; 'T2 &rarr; bool) &rarr; seq<'T1> &rarr; seq<'T2> &rarr; bool测试输入序列的任何一对相应元素是否满足给定的谓词.
filter : ('T &rarr; bool) &rarr; seq<'T> &rarr; seq<'T>返回一个新集合,其中仅包含给定谓词返回的集合元素 true .
find : ('T &rarr; bool) &rarr; seq<'T> &rarr; 'T返回给定函数返回的第一个元素 true .
findIndex : ('T &rarr; bool) &rarr; seq<'T> &rarr; int返回给定函数返回的第一个元素的索引 true .
fold : ('State &rarr; 'T &rarr; 'State) &rarr; 'State &rarr; seq<'T> &rarr; 'State将一个函数应用于集合的每个元素,通过计算线程化一个累加器参数.如果输入函数是f并且元素是i0 ... iN,则此函数计算f(...(fs i0)...)iN.
forall : ('T &rarr; bool) &rarr; seq<'T> &rarr; bool测试序列的所有元素是否满足给定的谓词.
forall2 : ('T1 &rarr; 'T2 &rarr; bool) &rarr; seq<'T1> &rarr; seq<'T2> &rarr; bool测试从两个序列中提取的所有元素对满足给定的谓词.如果一个序列比另一个序列短,则忽略较长序列的其余元素.
groupBy : ('T &rarr; 'Key) &rarr; seq<'T> &rarr; seq<'Key * seq<'T>>将密钥生成函数应用于序列的每个元素,并生成一系列唯一键.每个唯一键还包含与该键匹配的所有元素的序列.
head : seq<'T> &rarr; 'T返回序列的第一个元素.
init : int &rarr; (int &rarr; 'T) &rarr; seq<'T>生成一个新序列,当迭代时,通过调用给定函数返回连续元素,直到给定计数.调用函数的结果不会被保存,也就是说,根据需要重新应用函数来重新生成元素.该函数传递正在生成的项的索引.
initInfinite : (int &rarr; 'T) &rarr; seq<'T>生成一个新序列,当迭代时,将通过调用给定函数返回连续元素.调用该函数的结果不会被保存,也就是说,将根据需要重新应用该函数以重新生成元素.该函数被传递给正在生成的项的索引.
isEmpty : seq<'T> &rarr; bool测试一个序列是否有任何元素.
iter : ('T &rarr; unit) &rarr; seq<'T> &rarr; unit将给定的函数应用于集合的每个元素.
iter2 : ('T1 &rarr; 'T2 &rarr; unit) &rarr; seq<'T1> &rarr; seq<'T2> &rarr; unit同时将给定函数应用于两个集合.如果一个序列比另一个序列短,则忽略较长序列的其余元素.
iteri : (int &rarr; 'T &rarr; unit) &rarr; seq<'T> &rarr; unit将给定函数应用于集合的每个元素.传递给函数的整数表示元素的索引.
last : seq<'T> &rarr; 'T返回序列的最后一个元素.
length : seq<'T> &rarr; int返回序列的长度.
map : ('T &rarr; 'U) &rarr; seq<'T> &rarr; seq<'U>创建一个新集合,其元素是将给定函数应用于集合的每个元素的结果.在从对象检索的枚举数中使用MoveNext方法要求使用给定函数.
map2 : ('T1 &rarr; 'T2 &rarr; 'U) &rarr; seq<'T1> &rarr; seq<'T2> &rarr; seq<'U>创建一个新集合,其元素是将给定函数应用于两个序列中相应元素对的结果.如果一个输入序列比另一个短,则忽略较长序列的其余元素.
mapi : (int &rarr; 'T &rarr; 'U) &rarr; seq<'T> &rarr; seq<'U>创建一个新集合,其元素是将给定函数应用于集合的每个元素的结果.传递给函数的整数索引表示正在转换的元素的索引(从0开始).
max:seq<' T&GT; &RARR; 'T返回序列中所有元素中最大的元素,使用Operators.max进行比较.
maxBy : ('T &rarr; 'U) &rarr; seq<'T> &rarr; 'T返回序列中所有元素中最大的元素,通过在函数结果上使用Operators.max进行比较.
min:seq<'T> &RARR; 'T返回序列中所有元素的最低元素,使用Operators.min进行比较.
minBy : ('T &rarr; 'U) &rarr; seq<'T> &rarr; 'T返回序列中所有元素的最低元素,通过在函数结果上使用Operators.min进行比较.
nth : int &rarr; seq<'T> &rarr; 'T计算集合中的 nth 元素.
ofArray : 'T array &rarr; seq<'T>将给定数组视为序列.
ofList : 'T list &rarr; seq<'T>将给定列表视为序列.
pairwise : seq<'T> &rarr; seq<'T * 'T>返回输入序列及其前身中每个元素的序列,但第一个元素除外,它仅作为第二个元素的前身返回元素.
pick : ('T &rarr; 'U option) &rarr; seq<'T> &rarr; 'U将给定函数应用于连续元素,返回函数返回 Some 值的第一个值.
readonly : seq<'T> &rarr; seq<'T>创建一个委托给定序列对象的新序列对象.这确保了原型序列不能被类型转换重新发现和变异.例如,如果给定一个数组,则返回的序列将返回数组的元素,但是您无法将返回的序列对象强制转换为数组.
reduce : ('T &rarr; 'T &rarr; 'T) &rarr; seq<'T> &rarr; 'T将一个函数应用于序列的每个元素,通过计算线程化一个累加器参数.首先将函数应用于前两个元素.然后将此结果与第三个元素一起提供给函数,依此类推.返回最终结果.
scan : ('State &rarr; 'T &rarr; 'State) &rarr; 'State &rarr; seq<'T> &rarr; seq<'State>与Seq.fold类似,但按需计算并返回中间和最终结果的序列.
singleton : 'T &rarr; seq<'T>返回仅生成一个项目的序列.
skip : int &rarr; seq<'T> &rarr; seq<'T>返回跳过基础序列的指定数量元素的序列,然后生成序列的其余元素.
skipWhile : ('T &rarr; bool) &rarr; seq<'T> &rarr; seq<'T>返回一个序列,当迭代时,跳过基础序列的元素,而给定的谓词返回 true,,然后产生剩余的元素序列.
sort:seq<'T> &RARR; seq<'T>产生按键排序的序列.
sortBy : ('T &rarr; 'Key) &rarr; seq<'T> &rarr; seq<'T>将密钥生成函数应用于序列的每个元素,并生成按键排序的序列.使用Operators.compare实现的通用比较来比较密钥.
sum:seq< ^ T> &RARR; ^ T返回序列中元素的总和.
sumBy返回通过将函数应用于序列的每个元素而生成的结果的总和.
take : int &rarr; seq<'T> &rarr; seq<'T>返回序列的第一个元素,直到达到指定的数.
takeWhile : ('T &rarr; bool) &rarr; seq<'T> &rarr; seq<'T>返回一个序列,当迭代时,产生基础序列的元素,而给定的谓词返回 true,,然后不再返回其他元素.
toArray : seq<'T> &rarr; 'T[]从给定集合创建一个数组.
toList :seq<'T> &RARR; 'T list从给定集合创建一个列表.
truncate : int &rarr; seq<'T> &rarr; seq<'T>返回枚举时返回的序列不超过指定数量的元素.
tryFind : ('T &rarr; bool) &rarr; seq<'T> &rarr; 'T option返回给定函数返回的第一个元素 true,如果不存在这样的元素.
tryFindIndex : ('T &rarr; bool) &rarr; seq<'T> &rarr; int option返回满足给定谓词的序列中第一个元素的索引,如果不存在这样的元素,则返回.
tryPick : ('T &rarr; 'U option) &rarr; seq<'T> &rarr; 'U option将给定函数应用于连续元素,返回函数返回 Some 值的第一个值.
unfold : ('State &rarr; 'T * 'State option) &rarr; 'State &rarr; seq<'T>返回包含给定计算生成的元素的序列.
where : ('T &rarr; bool) &rarr; seq<'T> &rarr; seq<'T>返回一个新集合,其中仅包含给定谓词返回 true 的集合元素. Seq.filter的同义词.
windowed:int →  SEQ&LT;" T&GT; &RARR; seq<'T []>返回一个序列,该序列产生包含从输入序列中提取的元素的滑动窗口.每个窗口都以新数组的形式返回.
zip:seq<'T1> &RARR; SEQ&LT;" T2&GT; &RARR; seq<'T1 *'T2>将两个序列组合成一对列表.这两个序列不需要具有相同的长度和负数;当一个序列耗尽时,忽略另一个序列中的任何剩余元素.
zip3:seq<'T1> &RARR; SEQ&LT;" T2&GT; &RARR; SEQ&LT;" T3&GT; &RARR; seq<'T1 *'T2 *'T3>将三个序列组合成三元组列表.序列不需要具有相同的长度和减号;当一个序列耗尽时,忽略其他序列中的任何剩余元素.

以下示例演示了某些序列的用法以上功能 :

示例1

此程序创建一个空序列并在以后填充它并减去;

(* Creating sequences *)
let emptySeq = Seq.empty
let seq1 = Seq.singleton 20

printfn"The singleton sequence:"
printfn "%A " seq1
printfn"The init sequence:"

let seq2 = Seq.init 5 (fun n -> n * 3)
Seq.iter (fun i -> printf "%d " i) seq2
printfn""

(* converting an array to sequence by using cast *)
printfn"The array sequence 1:"
let seq3 = [| 1 .. 10 |] :> seq<int>
Seq.iter (fun i -> printf "%d " i) seq3
printfn""

(* converting an array to sequence by using Seq.ofArray *)
printfn"The array sequence 2:"
let seq4 = [| 2..2.. 20 |] |> Seq.ofArray
Seq.iter (fun i -> printf "%d " i) seq4
printfn""


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

The singleton sequence:
seq [20]
The init sequence:
0 3 6 9 12
The array sequence 1:
1 2 3 4 5 6 7 8 9 10
The array sequence 2:
2 4 6 8 10 12 14 16 18 20


请注意 :

  • Seq.empty方法创建一个空序列.

  • Seq .singleton方法只创建一个指定元素的序列.

  • Seq.init方法创建一个序列,通过使用给定的函数为其创建元素.

  • Seq.ofArray和Seq.ofList<'T>方法从数组和列表创建序列.

  • Seq.iter方法允许迭代序列.

示例2

Seq.unfold方法从计算函数生成一个序列,该函数接受一个状态并对其进行转换以生成序列中的每个后续元素.

以下函数产生前20个自然数 :

let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
printfn" "


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

The sequence seq1 contains numbers from 0 to 20.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20


示例3

Seq.truncate方法创建序列来自另一个序列,但将序列限制为指定数量的元素.

Seq.take方法创建一个新序列,其中包含从序列开始处指定数量的元素.

let mySeq = seq { for i in 1 .. 10 -> 3*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takeSeq = Seq.take 5 mySeq

printfn"The original sequence"
Seq.iter (fun i -> printf "%d " i) mySeq
printfn""

printfn"The truncated sequence"
Seq.iter (fun i -> printf "%d " i) truncatedSeq
printfn""

printfn"The take sequence"
Seq.iter (fun i -> printf "%d " i) takeSeq
printfn""



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

The original sequence
3 6 9 12 15 18 21 24 27 30
The truncated sequence
3 6 9 12 15
The take sequence
3 6 9 12 15