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

シーケンスの基本操作

次の表に、シーケンスデータ型の基本的な操作を示します。

説明
追加:seq <'T>→seq <' T>→seq <'T> 指定された2つの列挙を単一の連結列挙としてラップします。
平均:seq <^ T>→^ T シーケンス内の要素の平均を返します。
averageBy :( 'T→^ U)→seq <' T>→^ U シーケンスの各要素に関数を適用して生成された結果の平均を返します。
キャッシュ:seq <'T>→seq <' T> 入力シーケンスのキャッシュバージョンに対応するシーケンスを返します。
キャスト:IEnumerable→seq <'T> 緩く型付けされたシステムをラップします。型付きシーケンスとしてのコレクションシーケンス。
選択:( 'T→' Uオプション)→seq <'T>→seq <' U> 指定された関数をリストの各要素に適用します。関数が返す各要素の結果で構成されるリストを返しますSome
収集:( 'T→'コレクション)→seq <'T>→seq <' U> 指定された関数をシーケンスの各要素に適用し、すべての結果を連結します。
compareWith :( 'T→' T→int)→seq <'T>→seq <' T>→int 指定された比較関数を使用して、要素ごとに2つのシーケンスを比較します。
concat:seq <'コレクション>→seq <' T> 指定された列挙の列挙を単一の連結された列挙として結合します。
countBy :( 'T→' Key)→seq <'T>→seq <' Key * int> シーケンスの各要素にキー生成関数を適用し、シーケンスを返し、元のシーケンスでの一意のキーとその出現回数を生成します。
遅延:(ユニット→seq <'T>)→seq <' T> シーケンスの指定された遅延指定から構築されたシーケンスを返します。
異なる:seq <'T>→seq <' T> エントリの一般的なハッシュと等価性の比較に従って、重複するエントリを含まないシーケンスを返します。要素がシーケンス内で複数回出現する場合、それ以降の出現は破棄されます。
differentBy :( 'T→'キー)→seq <'T>→seq <' T> 指定されたキー生成関数によって返されるキーの一般的なハッシュと等価性の比較に従って、重複するエントリを含まないシーケンスを返します。要素がシーケンス内で複数回出現する場合、それ以降の出現は破棄されます。
空:seq <'T> 空のシーケンスを作成します。
正確に1つ:seq <'T>→' T シーケンスの唯一の要素を返します。
存在する:( 'T→bool)→seq <' T>→bool シーケンスのいずれかの要素が指定された述語を満たすかどうかをテストします。
存在2 :( 'T1→' T2→bool)→seq <'T1>→seq <' T2>→bool 入力シーケンスの対​​応する要素のペアが指定された述語を満たすかどうかをテストします。
フィルタ:( 'T→bool)→seq <' T>→seq <'T> 指定された述語が返すコレクションの要素のみを含む新しいコレクションを返します true
検索:( 'T→bool)→seq <' T>→ 'T 指定された関数が返す最初の要素を返します true
findIndex :( 'T→bool)→seq <' T>→int 指定された関数が返す最初の要素のインデックスを返します true
fold :( '状態→' T→ '状態)→'状態→seq <'T>→'状態 コレクションの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。入力関数がfで、要素がi0 ... iNの場合、この関数はf(...(fs i0)...)iNを計算します。
forall :( 'T→bool)→seq <' T>→bool シーケンスのすべての要素が指定された述語を満たしているかどうかをテストします。
forall2 :( 'T1→' T2→bool)→seq <'T1>→seq <' T2>→bool 2つのシーケンスから抽出された要素のすべてのペアが、指定された述語を満たすことをテストします。一方のシーケンスがもう一方のシーケンスよりも短い場合、長いシーケンスの残りの要素は無視されます。
groupBy :( 'T→'キー)→seq <'T>→seq <'キー* seq <'T >> シーケンスの各要素にキー生成関数を適用し、一意のキーのシーケンスを生成します。各一意のキーには、このキーに一致するすべての要素のシーケンスも含まれています。
ヘッド:seq <'T>→' T シーケンスの最初の要素を返します。
init:int→(int→ 'T)→seq <' T> 繰り返されると、指定された関数を呼び出すことにより、指定されたカウントまで連続する要素を返す新しいシーケンスを生成します。関数を呼び出した結果は保存されません。つまり、要素を再生成するために必要に応じて関数が再適用されます。関数には、生成されるアイテムのインデックスが渡されます。
initInfinite:(int→ 'T)→seq <' T> 繰り返されると、指定された関数を呼び出すことによって連続する要素を返す新しいシーケンスを生成します。関数を呼び出した結果は保存されません。つまり、要素を再生成するために必要に応じて関数が再適用されます。関数には、生成されるアイテムのインデックスが渡されます。
isEmpty:seq <'T>→bool シーケンスに要素があるかどうかをテストします。
iter :( 'T→ユニット)→seq <' T>→ユニット 指定された関数をコレクションの各要素に適用します。
iter2 :( 'T1→' T2→単位)→seq <'T1>→seq <' T2>→単位 指定された関数を2つのコレクションに同時に適用します。一方のシーケンスがもう一方のシーケンスよりも短い場合、長いシーケンスの残りの要素は無視されます。
iteri:(int→ 'T→unit)→seq <' T>→unit 指定された関数をコレクションの各要素に適用します。関数に渡される整数は、要素のインデックスを示します。
最後:seq <'T>→' T シーケンスの最後の要素を返します。
長さ:seq <'T>→int シーケンスの長さを返します。
マップ:( 'T→' U)→seq <'T>→seq <' U> コレクションの各要素に指定された関数を適用した結果を要素とする新しいコレクションを作成します。指定された関数は、オブジェクトから取得された列挙子でMoveNextメソッドを使用して要素が要求されるときに適用されます。
map2 :( 'T1→' T2→ 'U)→seq <' T1>→seq <'T2>→seq <' U> 指定された関数を2つのシーケンスの対​​応する要素のペアに適用した結果である要素を持つ新しいコレクションを作成します。一方の入力シーケンスがもう一方よりも短い場合、長いシーケンスの残りの要素は無視されます。
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を使用して比較した、シーケンスのすべての要素の最低値を返します。
n番目:int→seq <'T>→' T コレクションのn番目の要素を計算します。
ofArray: 'T配列→seq <' T> 指定された配列をシーケンスとして表示します。
ofList: 'Tリスト→seq <' T> 指定されたリストをシーケンスとして表示します。
ペアワイズ:seq <'T>→seq <' T * 'T> 2番目の要素の先行としてのみ返される最初の要素を除いて、入力シーケンスとその先行要素の各要素のシーケンスを返します。
ピック:( 'T→' Uオプション)→seq <'T>→' U 指定された関数を連続する要素に適用し、関数が返す最初の値を返します。 Some 値。
読み取り専用:seq <'T>→seq <' T> 指定されたシーケンスオブジェクトに委任する新しいシーケンスオブジェクトを作成します。これにより、型キャストによって元のシーケンスが再検出および変更されないことが保証されます。たとえば、配列が指定された場合、返されるシーケンスは配列の要素を返しますが、返されたシーケンスオブジェクトを配列にキャストすることはできません。
削減:( 'T→' T→ 'T)→seq <' T>→ 'T シーケンスの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。最初の2つの要素に関数を適用することから始めます。次に、この結果を3番目の要素とともに関数にフィードします。最終結果を返します。
スキャン:( '状態→' T→ '状態)→'状態→seq <'T>→seq <'状態> Seq.foldと同様ですが、オンデマンドで計算し、中間結果と最終結果のシーケンスを返します。
シングルトン: 'T→seq <' T> 1つのアイテムのみを生成するシーケンスを返します。
スキップ:int→seq <'T>→seq <' T> 基になるシーケンスの指定された数の要素をスキップして、シーケンスの残りの要素を生成するシーケンスを返します。
skipWhile :( 'T→bool)→seq <' T>→seq <'T> 指定された述語が返す間、繰り返されると、基になるシーケンスの要素をスキップするシーケンスを返します true, 次に、シーケンスの残りの要素を生成します。
ソート:seq <'T>→seq <' T> キー順に並べられたシーケンスを生成します。
sortBy :( 'T→'キー)→seq <'T>→seq <' T> シーケンスの各要素にキー生成関数を適用し、キー順に並べられたシーケンスを生成します。キーは、Operators.compareによって実装された一般的な比較を使用して比較されます。
合計:seq <^ T>→^ T シーケンス内の要素の合計を返します。
sumBy シーケンスの各要素に関数を適用して生成された結果の合計を返します。
取る:int→seq <'T>→seq <' T> 指定されたカウントまでのシーケンスの最初の要素を返します。
takeWhile :( 'T→bool)→seq <' T>→seq <'T> 繰り返されると、基になるシーケンスの要素を生成するシーケンスを返しますが、指定された述語は true, その後、それ以上の要素を返しません。
toArray:seq <'T>→' T [] 指定されたコレクションから配列を作成します。
toList:seq <'T>→' Tリスト 指定されたコレクションからリストを作成します。
切り捨て:int→seq <'T>→seq <' T> 列挙されたときに指定された数以下の要素を返すシーケンスを返します。
tryFind :( 'T→bool)→seq <' T>→ 'Tオプション 指定された関数が返す最初の要素を返します true, または None そのような要素が存在しない場合。
tryFindIndex :( 'T→bool)→seq <' T>→intオプション 指定された述語を満たすシーケンスの最初の要素のインデックスを返します。または None そのような要素が存在しない場合。
tryPick :( 'T→' Uオプション)→seq <'T>→' Uオプション 指定された関数を連続する要素に適用し、関数が返す最初の値を返します。 Some 値。
展開:( '状態→' T * '状態オプション)→'状態→seq <'T> 指定された計算によって生成された要素を含むシーケンスを返します。
ここで、:( 'T→bool)→seq <' T>→seq <'T> 指定された述語が返すコレクションの要素のみを含む新しいコレクションを返します true。Seq.filterの同義語。
ウィンドウ:int→seq <'T>→seq <' T []> 入力シーケンスから描画された要素を含むスライディングウィンドウを生成するシーケンスを返します。各ウィンドウは新しい配列として返されます。
zip:seq <'T1>→seq <' T2>→seq <'T1 *' T2> 2つのシーケンスをペアのリストに結合します。2つのシーケンスの長さは同じである必要はありません。一方のシーケンスが使い果たされると、もう一方のシーケンスの残りの要素は無視されます。
zip3:seq <'T1>→seq <' T2>→seq <'T3>→seq <' T1 * 'T2 *' T3> 3つのシーケンスを組み合わせてトリプルのリストにします。シーケンスの長さは同じである必要はありません。1つのシーケンスが使い果たされると、他のシーケンスの残りの要素は無視されます。

次の例は、上記の機能のいくつかの使用法を示しています-

例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メソッドは、指定された1つの要素のシーケンスを作成します。

  • 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