スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#によるLinq to Obj入門 (14) ToDictionary ToLookup

サンプルのためのレコード型とデータを準備しておきます。(いままでと同じものです。) 
 
type Emp = 
    {ID : int;//ID番号 
     name : string;//名前 
     height : float;//身長 
     sex :int //0が男,1が女 
     } 
     member this.disp () = 
        printfn "%2d %s %3.1f %A" this.ID this.name this.height this.sex 
 
サンプルデータを定義しておきます。 
 
Jhonが2人いることに留意しておいてください。 
 
let EmpSeq = seq[{ID = 1;name = "Jhon";height = 168.3;sex = 0}; 
                {ID = 3;name = "Jhon";height = 161.1;sex = 0}; 
                {ID = 8;name = "Kim";height = 168.3;sex = 1}; 
                {ID = 2;name = "Sawyer";height = 168.7;sex = 0}; 
                {ID = 13;name = "Michael";height = 155.0;sex = 0}; 
                {ID = 19;name = "Revecca";height = 154.8;sex = 1}; 
                {ID = 11;name = "Hugo";height = 176.6;sex = 0}; 
                {ID = 21;name = "Maggie";height = 149.1;sex = 1}; 
                {ID = 7;name = "Ben";height = 157.6;sex = 0}] 
 
 
ToDictionaryは「シークエンス」と、「シークエンスの要素からキーを作る関数」のタプルを引数にして、Dictionaryを返します。
Dictionaryについてはを参照してください。
シンタックスは次の通りです。
 
static member ToDictionary : 
        source:IEnumerable<'TSource> * 
        keySelector:Func<'TSource, 'TKey> -> Dictionary<'TKey, 'TSource> 
 
使用上の注意としては、「シークエンスの要素からキーを作る関数」によって生成される値が「一意である」こと、すなわち「重複がない」ようにするということです。もし2つ以上の要素に対して重複するキーを生成すると例外が発生します。
 

EmpSeqからIDをキーにしてDictionaryを作ります。
 
> let empDic = Enumerable.ToDictionary(EmpSeq,(fun p -> p.ID));;
 
val empDic : Dictionary<int,Emp> =
  dict
    [(1, {ID = 1;
          name = "Jhon";
          height = 168.3;
          sex = 0;}); (3, {ID = 3;
                           name = "Jhon";
                           height = 161.1;
                           sex = 0;}); (8, {ID = 8;
                                            name = "Kim";
                                            height = 168.3;
                                            sex = 1;}); (2, {ID = 2;
                                                             name = "Sawyer";
                                                             height = 168.7;
                                                             sex = 0;});
     (13, {ID = 13;
           name = "Michael";
           height = 155.0;
           sex = 0;}); (19, {ID = 19;
                             name = "Revecca";
                             height = 154.8;
                             sex = 1;}); (11, {ID = 11;
                                               name = "Hugo";
                                               height = 176.6;
                                               sex = 0;});
     (21, {ID = 21;
           name = "Maggie";
           height = 149.1;
           sex = 1;}); (7, {ID = 7;
                            name = "Ben";
                            height = 157.6;
                            sex = 0;})]
 
> empDic.[11];;
val it : Emp = {ID = 11;
                name = "Hugo";
                height = 176.6;
                sex = 0;}
                
 

名前をキーにしてDictionary作成を試みてみます。
 
> let empDic2 = Enumerable.ToDictionary(EmpSeq,(fun p -> p.name));;
System.ArgumentException: 同一のキーを含む項目が既に追加されています。
 
というようにJhonが2人いるので、例外が発生します。
このような同一キーに複数の値が対応する可能性があるときはDictionaryクラスの代わりにLookupクラスを使います。
 
ではLookupクラスの紹介です。
これはSystem.Linq名前空間で定義されており、次のようなシグネチャーをもちます。
 
type Lookup<'TKey, 'TElement> =  
    class
        interface ILookup<'TKey, 'TElement>
        interface IEnumerable<IGrouping<'TKey, 'TElement>>
        interface IEnumerable
    end
 
Enumerable.ToLookupメソッドを使って、名前をキーにしてLookupオブジェクトを生成してみます。
(引数はToDictionaryと同じです。)
 
> let empLU = Enumerable.ToLookup(EmpSeq,(fun p -> p.name));;
val empLU : ILookup<string,Emp>
 
キーから、値を求めてみます。
 
> empLU.["Jhon"];;
val it : seq<Emp> = seq [{ID = 1;
                          name = "Jhon";
                          height = 168.3;
                          sex = 0;}; {ID = 3;
                                      name = "Jhon";
                                      height = 161.1;
                                      sex = 0;}]
                                      
結果がseq<Emp>型になっていることに留意してください。
 
> empLU.["Hugo"];;
val it : seq<Emp> = seq [{ID = 11;
                          name = "Hugo";
                          height = 176.6;
                          sex = 0;}]
                                      
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。