F#-リスト
F#では、リストは同じタイプの順序付けられた不変の一連の要素です。これは、リンクリストのデータ構造とある程度同等です。
F#モジュール、 Microsoft.FSharp.Collections.List,リストに対する一般的な操作があります。ただし、F#はこのモジュールを自動的にインポートし、すべてのF#アプリケーションからアクセスできるようにします。
リストの作成と初期化
リストを作成するさまざまな方法は次のとおりです-
リストを使用する literals。
使用する cons (::)演算子。
を使用して List.init リストモジュールのメソッド。
いくつかを使用して syntactic constructs と呼ばれる List Comprehensions。
リテラルのリスト
この方法では、セミコロンで区切られた値のシーケンスを角括弧で囲んで指定するだけです。例-
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
短所(::)演算子
この方法では、またはを前に付けることでいくつかの値を追加できます cons-ing::演算子を使用して既存のリストに追加します。例-
let list2 = 1::2::3::4::5::6::7::8::9::10::[];;
[]は空のリストを示します。
リスト初期化メソッド
ListモジュールのList.initメソッドは、リストの作成によく使用されます。このメソッドのタイプは-です。
val init : int -> (int -> 'T) -> 'T list
最初の引数は新しいリストの目的の長さであり、2番目の引数は初期化関数であり、リスト内の項目を生成します。
例えば、
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
ここで、インデックス関数はリストを生成します。
リスト内包表記
リスト内包表記は、リストを生成するために使用される特別な構文構造です。
F#リスト内包構文には、範囲とジェネレーターの2つの形式があります。
範囲には構成があります-[開始..終了]および[開始..ステップ..終了]
例えば、
let list3 = [1 .. 10]
ジェネレーターの構成は-[コレクション内のxの場合... 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]
リストデータ型のプロパティ
次の表は、リストデータ型のさまざまなプロパティを示しています。
プロパティ | タイプ | 説明 |
---|---|---|
頭 | 'T | 最初の要素。 |
空の | 'Tリスト | 適切なタイプの空のリストを返す静的プロパティ。 |
IsEmpty | ブール | true リストに要素がない場合。 |
項目 | 'T | 指定されたインデックスの要素(ゼロベース)。 |
長さ | int | 要素の数。 |
尾 | 'Tリスト | 最初の要素のないリスト。 |
次の例は、これらのプロパティの使用法を示しています-
例
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
リストの基本的な演算子
次の表は、リストデータ型の基本的な操作を示しています。
値 | 説明 |
---|---|
追加: 'Tリスト→' Tリスト→ 'Tリスト | 最初のリストの要素とそれに続く2番目のリストの要素を含む新しいリストを返します。 |
平均: 'Tリスト→^ T | リスト内の要素の平均を返します。 |
averageBy :( 'T→^ U)→' Tリスト→^ U | リストの各要素に関数を適用して生成された要素の平均を返します。 |
選択:( 'T→' Uオプション)→ 'Tリスト→' Uリスト | 指定された関数をリストの各要素に適用します。関数が返す各要素の結果で構成されるリストを返しますSome。 |
収集:( 'T→' Uリスト)→ 'Tリスト→' Uリスト | リストの各要素に対して、指定された関数を適用します。すべての結果を連結し、結合されたリストを返します。 |
concat:seq <'Tリスト>→' Tリスト | 各リストの要素を順番に含む新しいリストを返します。 |
空: 'Tリスト | 指定されたタイプの空のリストを返します。 |
存在する:( 'T→bool)→' Tリスト→bool | リストのいずれかの要素が指定された述語を満たすかどうかをテストします。 |
存在2 :( 'T1→' T2→bool)→ 'T1リスト→' T2リスト→bool | リストの対応する要素のペアが指定された述語を満たすかどうかをテストします。 |
フィルタ:( 'T→bool)→' Tリスト→ 'Tリスト | 指定された述語が返すコレクションの要素のみを含む新しいコレクションを返します true。 |
検索:( 'T→bool)→' Tリスト→ 'T | 指定された関数が返す最初の要素を返します true。 |
findIndex :( 'T→bool)→' Tリスト→int | 指定された述語を満たすリストの最初の要素のインデックスを返します。 |
fold :( '状態→' T→ '状態)→'状態→ 'Tリスト→'状態 | コレクションの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。この関数は2番目の引数を取り、その引数とリストの最初の要素に関数を適用します。次に、この結果を2番目の要素とともに関数に渡します。最後に、最終結果を返します。入力関数がfで、要素がi0 ... iNの場合、この関数はf(...(fs i0)i1 ...)iNを計算します。 |
fold2 :( '状態→' T1→ 'T2→'状態)→ '状態→' T1リスト→ 'T2リスト→'状態 | 2つのコレクションの対応する要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。コレクションのサイズは同じである必要があります。入力関数がfで、要素がi0 ... iNおよびj0 ... jNの場合、この関数はf(...(fs i0 j0)...)iNjNを計算します。 |
foldBack :( 'T→'状態→ '状態)→' Tリスト→ '状態→'状態 | コレクションの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。入力関数がisfで、要素がi0 ... iNの場合、f i0(...(f iN s))を計算します。 |
foldBack2 :( 'T1→' T2→ '状態→'状態)→ 'T1リスト→' T2リスト→ '状態→'状態 | 2つのコレクションの対応する要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。コレクションのサイズは同じである必要があります。入力関数がfで、要素がi0 ... iNおよびj0 ... jNの場合、この関数はf i0 j0(...(f iN jN s))を計算します。 |
forall :( 'T→bool)→' Tリスト→bool | コレクションのすべての要素が指定された述語を満たしているかどうかをテストします。 |
forall2 :( 'T1→' T2→bool)→ 'T1リスト→' T2リスト→bool | コレクションの対応するすべての要素が、指定された述語をペアごとに満たすかどうかをテストします。 |
ヘッド: 'Tリスト→' T | リストの最初の要素を返します。 |
init:int→(int→ 'T)→' Tリスト | 各インデックスで指定されたジェネレーターを呼び出すことにより、リストを作成します。 |
isEmpty: 'Tリスト→bool | 戻り値 true リストに要素が含まれていない場合、 false そうでなければ。 |
iter :( 'T→ユニット)→' Tリスト→ユニット | 指定された関数をコレクションの各要素に適用します。 |
iter2 :( 'T1→' T2→ユニット)→ 'T1リスト→' T2リスト→ユニット | 指定された関数を2つのコレクションに同時に適用します。コレクションのサイズは同じである必要があります。 |
iteri:(int→ 'T→unit)→' Tリスト→unit | 指定された関数をコレクションの各要素に適用します。関数に渡される整数は、要素のインデックスを示します。 |
iteri2:(int→ 'T1→' T2→unit)→ 'T1list→' T2list→unit | 指定された関数を2つのコレクションに同時に適用します。コレクションのサイズは同じである必要があります。関数に渡される整数は、要素のインデックスを示します。 |
長さ: 'Tリスト→int | リストの長さを返します。 |
マップ:( 'T→' U)→ 'Tリスト→' Uリスト | コレクションの各要素に指定された関数を適用した結果である要素を持つ新しいコレクションを作成します。 |
map2 :( 'T1→' T2→ 'U)→' T1リスト→ 'T2リスト→' Uリスト | 指定された関数を2つのコレクションの対応する要素にペアごとに適用した結果である要素を持つ新しいコレクションを作成します。 |
map3 :( 'T1→' T2→ 'T3→' U)→ 'T1リスト→' T2リスト→ 'T3リスト→' Uリスト | 指定された関数を3つのコレクションの対応する要素に同時に適用した結果である要素を持つ新しいコレクションを作成します。 |
mapi:(int→ 'T→' U)→ 'Tリスト→' Uリスト | コレクションの各要素に指定された関数を適用した結果を要素とする新しいコレクションを作成します。関数に渡される整数インデックスは、変換される要素のインデックス(0から)を示します。 |
mapi2:(int→ 'T1→' T2→ 'U)→' T1リスト→ 'T2リスト→' Uリスト | List.mapiと似ていますが、同じ長さの2つのリストから対応する要素をマッピングします。 |
max: 'Tリスト→' T | Operators.maxを使用して比較した、リストのすべての要素の最大のものを返します。 |
maxBy :( 'T→' U)→ 'Tリスト→' T | 関数の結果でOperators.maxを使用して比較した、リストのすべての要素の最大値を返します。 |
min: 'Tリスト→' T | Operators.minを使用して比較した、リストのすべての要素の最低値を返します。 |
minBy :( 'T→' U)→ 'Tリスト→' T | 関数の結果でOperators.minを使用して比較した、リストのすべての要素の中で最も低いものを返します |
n番目: 'Tリスト→int→' T | リストへのインデックス。最初の要素のインデックスは0です。 |
ofArray: 'T []→' Tリスト | 指定された配列からリストを作成します。 |
ofSeq:seq <'T>→' Tリスト | 指定された列挙可能なオブジェクトから新しいリストを作成します。 |
パーティション:( 'T→bool)→' Tリスト* 'Tリスト | コレクションを2つのコレクションに分割します。これには、指定された述語が返す要素が含まれます。 true そして false それぞれ。 |
順列:(int→int)→ 'Tリスト→' Tリスト | 指定された順列に従ってすべての要素が順列されたリストを返します。 |
ピック:( 'T→' Uオプション)→ 'Tリスト→' U | 指定された関数を連続する要素に適用し、関数が返す最初の結果を返します Some いくつかの値のために。 |
削減:( 'T→' T→ 'T)→' Tリスト→ 'T | コレクションの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。この関数は、指定された関数をリストの最初の2つの要素に適用します。次に、この結果を3番目の要素とともに関数に渡します。最後に、最終結果を返します。入力関数がfで、要素がi0 ... iNの場合、この関数はf(...(f i0 i1)i2 ...)iNを計算します。 |
reduceBack :( 'T→' T→ 'T)→' Tリスト→ 'T | コレクションの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。入力関数がisfで、要素がi0 ... iNの場合、この関数はf i0(...(f iN-1 iN))を計算します。 |
レプリケート:(int→ 'T→' Tリスト) | 各インデックスで指定されたジェネレーターを呼び出すことにより、リストを作成します。 |
rev: 'Tリスト→' Tリスト | 要素を逆の順序で含む新しいリストを返します。 |
スキャン:( '状態→' T→ '状態)→'状態→ 'Tリスト→'状態リスト | コレクションの各要素に関数を適用し、計算を通じてアキュムレータ引数をスレッド化します。この関数は2番目の引数を取り、指定された関数をその引数とリストの最初の要素に適用します。次に、この結果を2番目の要素とともに関数に渡します。最後に、中間結果と最終結果のリストを返します。 |
scanBack :( 'T→'状態→ '状態)→' Tリスト→ '状態→'状態リスト | foldBackと同様ですが、中間結果と最終結果の両方を返します |
ソート: 'Tリスト→' Tリスト | Operators.compareを使用して、指定されたリストを並べ替えます。 |
sortBy :( 'T→'キー)→ 'Tリスト→' Tリスト | 指定されたプロジェクションによって指定されたキーを使用して、指定されたリストを並べ替えます。キーはOperators.compareを使用して比較されます。 |
sortWith :( 'T→' T→int)→ 'Tリスト→' Tリスト | 指定された比較関数を使用して、指定されたリストをソートします。 |
合計:^ Tリスト→^ T | リスト内の要素の合計を返します。 |
sumBy :( 'T→^ U)→' Tリスト→^ U | リストの各要素に関数を適用して生成された結果の合計を返します。 |
テール: 'Tリスト→' Tリスト | 最初の要素なしで入力リストを返します。 |
toArray: 'Tリスト→' T [] | 指定されたリストから配列を作成します。 |
toSeq: 'Tリスト→seq <' T> | 指定されたリストをシーケンスとして表示します。 |
tryFind :( 'T→bool)→' Tリスト→ 'Tオプション | 指定された関数が返す最初の要素を返します true。戻るNone そのような要素が存在しない場合。 |
tryFindIndex :( 'T→bool)→' Tリスト→intオプション | 指定された述語を満たすリストの最初の要素のインデックスを返します。戻るNone そのような要素が存在しない場合。 |
tryPick :( 'T→' Uオプション)→ 'Tリスト→' Uオプション | 指定された関数を連続する要素に適用し、関数が返す最初の結果を返します Someいくつかの値のために。そのような要素が存在しない場合は、None。 |
解凍:( 'T1 *' T2)リスト→ 'T1リスト*' T2リスト | ペアのリストを2つのリストに分割します。 |
unzip3 :( 'T1 *' T2 * 'T3)リスト→' T1リスト* 'T2リスト*' T3リスト | トリプルのリストを3つのリストに分割します。 |
zip: 'T1リスト→' T2リスト→( 'T1 *' T2)リスト | 2つのリストをペアのリストに結合します。2つのリストの長さは同じでなければなりません。 |
zip3: 'T1リスト→' T2リスト→ 'T3リスト→(' T1 * 'T2 *' T3)リスト | 3つのリストをトリプルのリストに結合します。リストの長さは同じでなければなりません。 |
次の例は、上記の機能の使用法を示しています-
例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 同じ目的のためのモジュールの機能-
let 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.