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.