F#序列

2018-12-15 15:16 更新

序列,像列表一样表示值的有序集合。 然而,当需要时,计算序列或序列表达式中的元素。 它们不是一次计算的,因此它们用于表示无限数据结构。

定义序列

序列使用下面的语法定义 

seq { expr }

例如,

let seq1 = seq { 1 .. 10 }

创建序列和序列表达式

与列表类似,您可以使用范围和推导来创建序列。

序列表达式可以用于创建顺序写入表达式。能做到这些 -

  • 通过指定的范围内。
  • 通过指定与递增或递减的范围内。
  • 通过使用收率关键字以产生成为该序列的一部分的值。
  • 通过使用→运算符。

下面的例子演示概念 

例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

对序列的基本操作

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

描述
append : seq<'T> → seq<'T> → seq<'T>封装了两个给定枚举作为单一串联枚举。
average : seq<^T> → ^T返回序列中的元素的平均值。
averageBy : ('T → ^U) → seq<'T> → ^U返回由将所述函数应用于所述序列中的每个元件产生的结果的平均值。
cache : seq<'T> → seq<'T>返回对应于输入序列的高速缓存版本的序列。
cast : IEnumerable → seq<'T>包装松散类型的系统。集合序列作为输入序列。
choose : ('T → 'U option) → seq<'T> → seq<'U>将给定的函数应用于列表的每个元素。 返回由函数returns Some的每个元素的结果组成的列表。
collect : ('T → 'Collection) → seq<'T> → seq<'U>应用于给定的功能,该序列中的每个元素和并置的所有结果。
compareWith : ('T → 'T → int) → seq<'T> → seq<'T> → int比较使用给定比较函数,元件由元件两个序列。
concat : seq<'Collection> → seq<'T>结合给定的枚举-的-枚举作为单一串联枚举。
countBy : ('T → 'Key) → seq<'T> → seq<'Key * int>施加产生关键功能的序列中的每个元素,并返回产生独特键和它们原来的顺序出现次数的顺序。
delay : (unit → seq<'T>) → seq<'T>返回从一个序列的给定延迟规范构建的序列。
distinct : seq<'T> → seq<'T>返回包含根据上的条目通用散列和平等的比较没有重复的条目顺序。如果序列中多次出现的元件则以后出现被丢弃。
distinctBy : ('T → 'Key) → seq<'T> → seq<'T>返回包含根据对给定生成键返回功能键通用散列和平等的比较没有重复的条目顺序。如果序列中多次出现的元件则以后出现被丢弃。
empty : seq<'T>创建一个空的序列。
exactlyOne : seq<'T> → 'T返回序列的唯一元素。
exists : ('T → bool) → seq<'T> → bool如果序列中的任何元素满足给定谓词测试。
exists2 : ('T1 → 'T2 → bool) → seq<'T1> → seq<'T2> → bool测试如果任何一对输入序列的相应元件的满足给定谓词。
filter : ('T → bool) → seq<'T> → seq<'T>返回包含只对给定的谓词返回true的集合中的元素一个新的集合。
find : ('T → bool) → seq<'T> → 'T返回该给定函数返回true的第一个元素。
findIndex : ('T → bool) → seq<'T> → int返回该给定函数返回true的第一个元素的索引。
fold : ('State → 'T → 'State) → 'State → seq<'T> → 'State应用一个函数集合中的每个元素,穿线通过计算一个累加器参数。如果输入函数是f和元素I0 ...中,则该函数计算F(...(FS I0)...)中。
forall : ('T → bool) → seq<'T> → bool如果测试序列的所有元素满足给定谓词。
forall2 : ('T1 → 'T2 → bool) → seq<'T1> → seq<'T2> → bool测试的所有对从两个序列绘制元件的满足给定的谓词。如果一个序列比另一个短则较长序列的其余元素将被忽略。
groupBy : ('T → 'Key) → seq<'T> → seq<'Key * seq<'T>>施加产生关键功能的序列中的每个元素,并产生唯一键的一个序列。每个独特的项也已包含匹配该键,所有元素的序列。
head : seq<'T> → 'T返回序列的第一个元素。
init : int → (int → 'T) → seq<'T>生成一个新的序列,迭代时,通过调用给定函数,直到给定的计数返回连续元素。调用函数的结果不被保存,即,功能被重新施加必要重新生成的元素。所述函数传递正在生成的项的索引。
initInfinite : (int → 'T) → seq<'T>生成一个新的序列,迭代的时候,会通过调用给定函数返回连续元素。调用函数的结果不被保存,即,该函数将被重新应用在必要时重新生成的元素。所述函数传递正在生成的项的索引。
isEmpty : seq<'T> → bool测试序列是否有任何元素。
iter : ('T → unit) → seq<'T> → unit应用于给定的功能到集合中的每个元素。
iter2 : ('T1 → 'T2 → unit) → seq<'T1> → seq<'T2> → unit适用于给定函数同时两个集合。如果一个序列比另一个短则较长序列的其余元素将被忽略。
iteri : (int → 'T → unit) → seq<'T> → unit应用于给定的功能到集合中的每个元素。传递给函数的整数表示的元素的索引。
last : seq<'T> → 'T返回序列的最后一个元素。
length : seq<'T> → int返回序列的长度。
map : ('T → 'U) → seq<'T> → seq<'U>创建一个新的集合的元素是施加给定函数对每个集合中的元素的结果。作为元素是使用从对象检索统计员MoveNext方法所要求的给定的函数将被应用。
map2 : ('T1 → 'T2 → 'U) → seq<'T1> → seq<'T2> → seq<'U>创建一个新的集合的元素是施加给定的功能,以相应的对从两个序列元件的结果。如果一个输入序列比另一个短则较长序列的其余元素将被忽略。
mapi : (int → 'T → 'U) → seq<'T> → seq<'U>创建一个新的集合的元素是施加给定函数对每个集合中的元素的结果。传递给函数的整数索引表示正在转变元素的索引(从0开始)。
max : seq<'T> → 'T返回的最大序列的所有元素,通过使用Operators.max比较。
maxBy : ('T → 'U) → seq<'T> → 'T返回的最大序列的所有元素,通过在函数结果使用Operators.max比较。
min : seq<'T> → 'T返回最低序列的所有元素,通过使用Operators.min比较。
minBy:('T→'U)→SEQ <'T>→'T返回最低序列的所有元素,通过在函数结果使用Operators.min比较。
nth : int → seq<'T> → 'T计算集合中的第n个元素。
ofArray : 'T array → seq<'T>意见给出数组作为序列。
ofList : 'T list → seq<'T>意见给出列表作为序列。
pairwise : seq<'T> → seq<'T * 'T>返回输入序列及其前身各要素的序列,这是只有返回作为第二元件的前身的第一个元件的异常。
pick : ('T → 'U option) → seq<'T> → 'U将给定函数应用于连续元素,返回函数返回Somevalue的第一个值。
readonly : seq<'T> → seq<'T>创建一个新的序列对象委托给指定的序列对象。这确保了原始序列不能被重新发现,并通过一个类型转换突变。例如,如果给一个数组返回序列将返回数组中的元素,但不能转换返回序列对象的数组。
reduce : ('T → 'T → 'T) → seq<'T> → 'T适用的功能的序列中的每个元素,穿线通过计算一个累加器参数。通过将所述函数应用于所述第一两个元素开始。然后养活这个结果到函数与第三个元素等等一起。返回的最终结果。
scan : ('State → 'T → 'State) → 'State → seq<'T> → seq<'State>像Seq.fold,但计算点播和返回的中间和最终结果的顺序。
singleton : 'T → seq<'T>返回只产生一个项目序列。
skip : int → seq<'T> → seq<'T>返回跳过基础序列的元素的指定号码,然后产生该序列的其余元素的序列。
skipWhile : ('T → bool) → seq<'T> → seq<'T>返回一个序列,迭代时,跳过基础序列的元素,同时给定的谓词返回true,然后产生序列的剩余的元素。
sort : seq<'T> → seq<'T>产量提高按键有序的序列。
sortBy : ('T → 'Key) → seq<'T> → seq<'T>施加产生关键功能的序列中的每个元素和屈服通过键有序序列。键是使用由Operators.compare实现通用的比较比较。
sum : seq<^T> → ^T返回序列中的元素的总和。
sumby返回由将所述函数应用于所述序列中的每个元件产生的结果的总和。
take : int → seq<'T> → seq<'T>返回序列的第一个元素到一个指定计数。
takeWhile : ('T → bool) → seq<'T> → seq<'T>返回一个序列,迭代时,得到的基础序列的元素,同时给定的谓词返回true,然后返回没有进一步的元素。
toArray : seq<'T> → 'T[]创建从给定集合的数组。
toList : seq<'T> → 'T list创建从给定集合列表。
truncate : int → seq<'T> → seq<'T>返回序列枚举时返回比元素指定数量不多。
tryFind : ('T → bool) → seq<'T> → 'T option返回给定函数返回true的第一个元素,或者没有这样的元素存在。
tryFindIndex : ('T → bool) → seq<'T> → int option返回序列中满足给定谓词的第一个元素的索引,如果没有此类元素,则返回None。
tryPick : ('T → 'U option) → seq<'T> → 'U option将给定函数应用于连续元素,返回函数返回Somevalue的第一个值。
unfold : ('State → 'T * 'State option) → 'State → seq<'T>返回包含由给定运算所产生的元素的序列。
where : ('T → bool) → seq<'T> → seq<'T>返回一个新集合,只包含给定谓词returnstrue的集合的元素。 Seq.filter的同义词。
windowed : int → seq<'T> → seq<'T []>返回国债收益率滑动包含从输入序列绘制的元素的窗口序列。每个窗口返回为一个新的数组。
zip : seq<'T1> → seq<'T2> → seq<'T1 * 'T2>结合了两个序列成对的列表。两个序列不必具有相等的长度 - 当一个序列被耗尽在另一序列中的任何剩余的元素将被忽略。
zip3 : seq<'T1> → seq<'T2> → seq<'T3> → 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
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号