Fsharp-lists

提供:Dev Guides
移動先:案内検索

F#-リスト

F#では、リストは同じタイプの要素の順序付けられた不変のシリーズです。 これは、リンクリストのデータ構造とある程度同等です。

F#モジュール Microsoft.FSharp.Collections.List には、リストに対する一般的な操作があります。 ただし、F#はこのモジュールを自動的にインポートし、すべてのF#アプリケーションからアクセスできるようにします。

リストの作成と初期化

以下は、リストを作成するさまざまな方法です-

  • リスト literals を使用します。
  • cons (::)演算子を使用します。
  • Listモジュールの List.init メソッドを使用します。
  • 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::[];;

[] denotes an empty list.

リストinitメソッド

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つの形式があります。

範囲には構造があります-[start .. end]および[start .. ステップ.. end]

例えば、

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]

リストデータ型のプロパティ

次の表は、リストのデータ型のさまざまなプロパティを示しています-

Property Type Description
Head 'T The first element.
Empty 'T list A static property that returns an empty list of the appropriate type.
IsEmpty bool *true *if the list has no elements.
Item 'T The element at the specified index (zero-based).
Length int The number of elements.
Tail 'T list The list without the first element.

次の例は、これらのプロパティの使用を示しています-

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

リストの基本的な演算子

次の表は、リストのデータ型の基本的な操作を示しています-

Value Description
append : 'T list → 'T list → 'T list Returns a new list that contains the elements of the first list followed by elements of the second.
average : 'T list → ^T Returns the average of the elements in the list.
averageBy : ('T → ^U) → 'T list → ^U Returns the average of the elements generated by applying the function to each element of the list.
choose : ('T → 'U option) → 'T list → 'U list Applies the given function to each element of the list. Returns the list comprised of the results for each element where the function returns* Some*.
collect : ('T → 'U list) → 'T list → 'U list For each element of the list, applies the given function. Concatenates all the results and return the combined list.
concat : seq<'T list> → 'T list Returns a new list that contains the elements of each the lists in order.
empty : 'T list Returns an empty list of the given type.
exists : ('T → bool) → 'T list → bool Tests if any element of the list satisfies the given predicate.
exists2 : ('T1 → 'T2 → bool) → 'T1 list → 'T2 list → bool Tests if any pair of corresponding elements of the lists satisfies the given predicate.
filter : ('T → bool) → 'T list → 'T list Returns a new collection containing only the elements of the collection for which the given predicate returns true.
find : ('T → bool) → 'T list → 'T Returns the first element for which the given function returns true.
findIndex : ('T → bool) → 'T list → int Returns the index of the first element in the list that satisfies the given predicate.
fold : ('State → 'T → 'State) → 'State → 'T list → 'State Applies a function to each element of the collection, threading an accumulator argument through the computation. This function takes the second argument, and applies the function to it and the first element of the list. Then, it passes this result into the function along with the second element, and so on. Finally, it returns the final result. If the input function is f and the elements are i0…​iN, then this function computes f (…​ (f s i0) i1 …​) iN.
fold2 : ('State → 'T1 → 'T2 → 'State) → 'State → 'T1 list → 'T2 list → 'State Applies a function to corresponding elements of two collections, threading an accumulator argument through the computation. The collections must have identical sizes. If the input function is f and the elements are i0…​iN and j0…​jN, then this function computes f (…​ (f s i0 j0)…​) iN jN.
foldBack : ('T → 'State → 'State) → 'T list → 'State → 'State Applies a function to each element of the collection, threading an accumulator argument through the computation. If the input function isf and the elements are i0…​iN then computes f i0 (…​(f iN s)).
foldBack2 : ('T1 → 'T2 → 'State → 'State) → 'T1 list → 'T2 list → 'State → 'State Applies a function to corresponding elements of two collections, threading an accumulator argument through the computation. The collections must have identical sizes. If the input function is f and the elements are i0…​iN and j0…​jN, then this function computes f i0 j0 (…​(f iN jN s)).
forall : ('T → bool) → 'T list → bool Tests if all elements of the collection satisfy the given predicate.
forall2 : ('T1 → 'T2 → bool) → 'T1 list → 'T2 list → bool Tests if all corresponding elements of the collection satisfy the given predicate pairwise.
head : 'T list → 'T Returns the first element of the list.
init : int → (int → 'T) → 'T list Creates a list by calling the given generator on each index.
isEmpty : 'T list → bool Returns true *if the list contains no elements, false *otherwise.
iter : ('T → unit) → 'T list → unit Applies the given function to each element of the collection.
iter2 : ('T1 → 'T2 → unit) → 'T1 list → 'T2 list → unit Applies the given function to two collections simultaneously. The collections must have identical size.
iteri : (int → 'T → unit) → 'T list → unit Applies the given function to each element of the collection. The integer passed to the function indicates the index of element.
iteri2 : (int → 'T1 → 'T2 → unit) → 'T1 list → 'T2 list → unit Applies the given function to two collections simultaneously. The collections must have identical size. The integer passed to the function indicates the index of element.
length : 'T list → int Returns the length of the list.
map : ('T → 'U) → 'T list → 'U list Creates a new collection whose elements are the results of applying the given function to each of the elements of the collection.
map2 : ('T1 → 'T2 → 'U) → 'T1 list → 'T2 list → 'U list Creates a new collection whose elements are the results of applying the given function to the corresponding elements of the two collections pairwise.
map3 : ('T1 → 'T2 → 'T3 → 'U) → 'T1 list → 'T2 list → 'T3 list → 'U list Creates a new collection whose elements are the results of applying the given function to the corresponding elements of the three collections simultaneously.
mapi : (int → 'T → 'U) → 'T list → 'U list Creates a new collection whose elements are the results of applying the given function to each of the elements of the collection. The integer index passed to the function indicates the index (from 0) of element being transformed.
mapi2 : (int → 'T1 → 'T2 → 'U) → 'T1 list → 'T2 list → 'U list Like List.mapi, but mapping corresponding elements from two lists of equal length.
max : 'T list → 'T Returns the greatest of all elements of the list, compared by using Operators.max.
maxBy : ('T → 'U) → 'T list → 'T Returns the greatest of all elements of the list, compared by using Operators.max on the function result.
min : 'T list → 'T Returns the lowest of all elements of the list, compared by using Operators.min.
minBy : ('T → 'U) → 'T list → 'T Returns the lowest of all elements of the list, compared by using Operators.min on the function result
nth : 'T list → int → 'T Indexes into the list. The first element has index 0.
ofArray : 'T [] → 'T list Creates a list from the given array.
ofSeq : seq<'T> → 'T list Creates a new list from the given enumerable object.
partition : ('T → bool) → 'T list* 'T list Splits the collection into two collections, containing the elements for which the given predicate returns true *and false *respectively.
permute : (int → int) → 'T list → 'T list Returns a list with all elements permuted according to the specified permutation.
pick : ('T → 'U option) → 'T list → 'U Applies the given function to successive elements, returning the first result where function returns* Some *for some value.
reduce : ('T → 'T → 'T) → 'T list → 'T Applies a function to each element of the collection, threading an accumulator argument through the computation. This function applies the specified function to the first two elements of the list. It then passes this result into the function along with the third element, and so on. Finally, it returns the final result. If the input function is f and the elements are i0…​iN, then this function computes f (…​ (f i0 i1) i2 …​) iN.
reduceBack : ('T → 'T → 'T) → 'T list → 'T Applies a function to each element of the collection, threading an accumulator argument through the computation. If the input function isf and the elements are i0…​iN, then this function computes f i0 (…​(f iN-1 iN)).
replicate : (int → 'T → 'T list) Creates a list by calling the given generator on each index.
rev : 'T list → 'T list Returns a new list with the elements in reverse order.
scan : ('State → 'T → 'State) → 'State → 'T list → 'State list Applies a function to each element of the collection, threading an accumulator argument through the computation. This function takes the second argument, and applies the specified function to it and the first element of the list. Then, it passes this result into the function along with the second element and so on. Finally, it returns the list of intermediate results and the final result.
scanBack : ('T → 'State → 'State) → 'T list → 'State → 'State list Like foldBack, but returns both the intermediate and final results
sort : 'T list → 'T list Sorts the given list using Operators.compare.
sortBy : ('T → 'Key) → 'T list → 'T list Sorts the given list using keys given by the given projection. Keys are compared using Operators.compare.
sortWith : ('T → 'T → int) → 'T list → 'T list Sorts the given list using the given comparison function.
sum : ^T list → ^T Returns the sum of the elements in the list.
sumBy : ('T → ^U) → 'T list → ^U Returns the sum of the results generated by applying the function to each element of the list.
tail : 'T list → 'T list Returns the input list without the first element.
toArray : 'T list → 'T [] Creates an array from the given list.
toSeq : 'T list → seq<'T> Views the given list as a sequence.
tryFind : ('T → bool) → 'T list → 'T option Returns the first element for which the given function returns* true*. Return *None *if no such element exists.
tryFindIndex : ('T → bool) → 'T list → int option Returns the index of the first element in the list that satisfies the given predicate. Return* None *if no such element exists.
tryPick : ('T → 'U option) → 'T list → 'U option Applies the given function to successive elements, returning the first result where function returns* Some for some value. If no such element exists then return None*.
unzip : ('T1 'T2) list → 'T1 list 'T2 list Splits a list of pairs into two lists.
unzip3 : ('T1 'T2 'T3) list → 'T1 list 'T2 list 'T3 list Splits a list of triples into three lists.
zip : 'T1 list → 'T2 list → ('T1 *'T2) list Combines the two lists into a list of pairs. The two lists must have equal lengths.
zip3 : 'T1 list → 'T2 list → 'T3 list → ('T1* 'T2 * 'T3) list Combines the three lists into a list of triples. The lists must have equal lengths.

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

例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

「fold」操作は、リスト内の各要素に関数を適用し、関数の結果をアキュムレーター変数に集約し、フォールド操作の結果としてアキュムレーターを返します。

実施例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.