コレクションの概要
F#には、様々なコレクション型が用意されています。コレクションにはそれぞれの型によって向き・不向きが存在しています。F#コレクションを利用する際は、ニーズによって適切なコレクション型を選択するようにしましょう。
また、F#コレクションは .NET の System.Collections/System.Collections.Generics名前空間 に定義されているコレクション型とは別に定義されています。これは、F#コレクション型がオブジェクト指向ではなく関数型プログラミングの観点から設計されているためです。より具体的には、配列コレクション(= array)のみが要素の再代入が可能となっています(= mutable)。それ以外のF#コレクションでは元のコレクションの要素に対して再代入はできず、要素を変更した場合は新しいコレクションインスタンスが作成されます。
F#コレクション型一覧
次の表はF#コレクション型を表しています。
型 | 概要 |
---|---|
list<'T> | すべてが同じ型であり、順序付けされた一連の immutable な値を要素にもったコレクション。LinkedListとして実装されています。 |
array<'T> | すべてが同じ型であり、連続した mutable な値を要素にもった固定サイズのコレクション。 |
seq<'T> | すべてが同じ型の論理的な一連の要素をもっているコレクション。seqは大規模な順序付けされたデータコレクションですが、必ずしもすべての要素をしようすることを期待していない場合に、特に便利です。個々のseq要素は必要に応じて計算されるため、すべての要素が使用されない場合、seq は list よりもパフォーマンスがよくなります。seq<'T>は、IEnumerable<'T> のエイリアスでもあります。そのため、.NETのコレクション型を seq<'T> として使用することも可能です。 |
map<'TKey, 'TValue> | immutableな要素を持つ辞書型コレクションです。要素はキーを利用してアクセスします。 |
set<'T> | 2分木に基づいた、重複なしのimmutableな集合です。要素の比較はSystem.IComparableを利用して、同一性をチェックします。 |
list<'T>
list<'T>は 連結リスト (= Linked list) と言われるデータ構造をしているコレクション型です。array<'T>とは違い、すべての要素を書き換え不可なimmutableな値としてもっています。list<'T>は一般的に特定のインデックスの要素を取得したり、特定の要素の検索の実行に関しては低速であるため、注意が必要です。この特性を踏まえて利用しないと、プログラムの速度面でボトルネックとなりかねないため注意が必要です。
次のサンプルは基本的な list<'T> の使い方を示しています。
list<'T>には、リストを操作するための演算子も用意されています。
また、list<'T>コレクションのよく使うような特定の値についてはプロパティが用意されています。
プロパティ名 | 型 | 概要 |
---|---|---|
Head | 'T | 最初の要素 |
Empty | 'T list | 空のリストを返す静的プロパティ |
IsEmpty | bool | リストに要素がない場合, true |
Item | 'T | 指定されたインデックスの要素を返す |
Length | int | リストの要素数 |
Tail | 'T list | 最初の要素を除いたリスト |
また、list<'T>を操作するための便利な関数が Listモジュール に集められています。詳細は Collections.Listモジュールを参照ください。
array<'T>
array<'T> も list<'T> とほぼ同様の特性を持っています。しかし、各要素が書き換え可能なmutableな値であることと、特定のインデックスの要素を高速に取得できる点が大きく異なります。要素が immutable / mutable の違いに目が行きがちですが、要素アクセスの速度差もあることは頭に入れておいたほうがよいでしょう
次のサンプルは基本的な array<'T> の使い方を示しています。
また、array<'T>を操作するための便利な関数が Arrayモジュール に集められています。詳細は Collections.Arrayモジュール を参照ください。
seq<'T>
seq<'T>は、1つの型に基づく論理的な一連のデータ群です。seq<'T>は大規模かつ順序付けされたデータの集まりですが、必ずしもすべての要素を使用するとは限らない場合に特に有効なコレクションです。個々の要素は必要に応じられたときにはじめて計算されるため、すべての要素が使用されるわけではない状況では、list<'T> や array<'T> よりも優れたパフォーマンスを得られます。
seq<'T>は、IEnumerableインターフェースのエイリアスでもあります。そのため、.NETのコレクション型(= System.Collections or System.Collections.Generics)をseq<'T>として扱うことができます。また、Collections.Arrayモジュールはseq<'T>を伴う操作もサポートしています。
シーケンス式
シーケンス式は seq<'T> に評価される式のことです。次のサンプルはシーケンス式の簡単な使い方を示しています。また、seq<'T>を操作するための便利な関数が Seqモジュール に集められています。詳細は Collections.Seqモジュールを参照ください。
map<'TKey,'TValue>
map<'TKey, 'TValue>は、いわゆる辞書型のデータ構造を持っている型です。辞書型のデータ構造とは、キーと値で1つの要素となります。キーを指定することで、値にアクセスすることができます。
次のサンプルは基本的な map<'TKey, 'TValue> の使い方を示しています。
また、map<'TKey, 'TValue>を操作するための便利な関数が Mapモジュール に集められています。詳細は Collections.Mapモジュールを参照ください。
set<'T>
set<'T>は、ハッシュテーブルを利用したデータ型です。重複する値を含まないコレクションを利用したい場合に便利です。値が重複するかどうかのチェックはSystem.IComparableインターフェースを利用して行われます。そのため、正しく動作させるには要素の型に対して、System.IComparableを正しく実装する必要があります。
次のサンプルは基本的な set<'T> の使い方を示しています。
また、set<'T>を操作するための便利な関数が Setモジュール に集められています。詳細は Collections.Setモジュールを参照ください。