2011-11-15 15 views
0

私は異なるシステムから2セットのデータを持っています。約20,000件を記録しています。データの1つのセットはList<Objects>で、もう1つは制御できないシステムのレコードセットです(レコードのみを要求しレコードセットを受け取ることができます)。2つの大きなデータセットを介して入れ子になったループ

2つのリストの間にあるデータをマージする必要があります。両方のリストに存在するキーを照合するには、Recordsetのデータを一致するオブジェクト構造に入れます。私が試したネストループは完全に遅すぎます。

マッチを取得して次のオブジェクトに移動する方法はありますか?

EDIT:既存のコード

これは非常に基本的なネストされたループ

results = _sr.SearchLst(ut.ToString(), searchSettings); 

foreach (BL.Packet ePacket in eList) { 

    for (Int32 j = 0; j < results.Rows.Length; j++) { 

     String acckey = results.Rows[0].Data.GetValue(1).ToString(); 
     String taskname = results.Rows[0].Data.GetValue(2).ToString(); 

     if (acckey == ePacket.RecKey.ToString()) { 
      ePacket.prop1 = taskname; 
      ePacket.prop2 = acckey; 
     } 
    } 
} 

である私はまた、LINQのを見ましたが、二つが一緒に行くだろうかの把握を得ることができませんでした...とにかくLinqがもっと速くなるか分からない。

解決策:

これは基本的に私がやったことです。

//move object from list to dictionary 
var dict = eList.Cast<BaseObj>().ToDictionary(o => o.RecKey, o => o); 

results = _sr.SearchLst(ut.ToString(), searchSettings); 
if (results.Rows.Length > 0) { 

    //loop through all rows in recordset 
    for (Int32 j = 0; j < results.Rows.Length; j++) { 
     id = Convert.ToInt32(results.Rows[j].Data.GetValue(1)); 
     taskname = results.Rows[j].Data.GetValue(2).ToString(); 

     if (dict.ContainsKey(id)) { 
      //recordset id found in dictionary, so grab taskname 
      ePacket = ((BL.Packet)dict[id]); 
      ePacket.prop1 = taskname; 
     } 
    } 
} 

//move dictionary back to list 
List<BaseObj> eListReturn = new List<BaseObj>(dict.Values); 
return eListReturn; 

お手数をおかけしております。

+0

sort-merge join例でより多くの情報を使用すると、LINQを使用してそれらを結合してみましたか? – CaffGeek

+1

既存のコードを投稿してください。 –

+0

あなたが言及したキーの根底にあるタイプ - 「存在するキーとのマッチング」とは何ですか? – sll

答えて

2

メモリ内にあるリストコレクションでDictionary<TypeOfKey, SomeObject>を使用し、キーをキーに、オブジェクトを値として辞書に入力します。

レコードセットをループします。ディクショナリを使用すると、一致する要素のO(1)ルックアップを行うことができるので、メモリ内コレクションのループを排除できます。

+0

リストをディクショナリに変換する(またはリストをディクショナリに追加する)処理は高速ですか? – Metallicraft

+0

アイデアを広げていただけますか?おかげで、 – Metallicraft

0

キーを使用してアクセスできるRecordSetオブジェクトとそのAPIに抽象レイヤーを書き込むことができます。これは、キーからRecordSetまでの辞書のようなものです。

各コレクションに1つずつ、2つの反復があります。 2回の繰り返しはO(N)ですが、ネストされたループはO(N^2)です。

3

このお試しください:インフォ場合に2枚に参加するhttp://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

(参照用旧メッセージ)

使用LINQ:ここにLINQの追加の参考のために101個のサンプルを

var Object = from o in Objects 
      join r in RecordSet equal o.YourKey equal r.YourForeignKey 
      select Object { x = r.YourProperty }; 

をしています単一のIEnumerable(リストのような)

var combinedData = from i in listItems 
        join r in recordSet on r.ID equals i.ID 
        select new { i.Name, r.Property }; 

よう 何かがここへのリンクですが、多くはそこにあり、それはあなたが探しているものを正確に行うことで、非常に高速です、あなたの.NETプラットフォーム用のLINQの例をグーグル、また、LINQ http://www.dotnetperls.com/join を使用して参加します。

同様のスレッドのためにSOを見た後、私はここで要約するかなり役に立ついくつかのものを見つけました。問題は、ループの内側の括弧で何をしたいかわからないということです。

「ガジェット」のリストとキーで結合できる「ウィジェット」のセットだけが必要だとします。あなたがウィジェットやガジェットの束が新しいwhatsitsに参加したい場合は

オブジェクト - 多分あなたは、チャートや何かの使用のために、この例で平らなテーブルを構築している:

var whatsits = from w in widgets 
       join g in gadgets on w.gadgetID equal g.ID 
       select new whatsit { name = w.name, id = w.ID }; 

を、あなたが取得したい場合ウィジェットの束は、ガジェット、ガジェットプロパティ=いくつかの値と合流した後、あなたが最初のガジェットを収集し、各ガジェット上で動作しないし、そのようにように新しいコレクションに対するforeach:

var widgetList = from w in widgets 
       join g in gadgets on w.gadgetID equals g.ID 
       where g.Name = "whatsit" 
       select w; 

foreach (widget w in widgetList) 
{ 
    // Do a bunch of stuff to each widget 
} 

注意、それはあるかもしれません上記のLINQのパフォーマンステストを行う価値があります最初はより良いウィジェットを実行するか、結合の最初のガジェットを実行します。

+0

ありがとう、私もこれを試し、それが役立つかどうかを確認します。 – Metallicraft

+0

サンプルを更新して、内側の括弧にいくつかのコードを追加しました。おかげで – Metallicraft

+0

あなたの括弧内のコードに基づいて、あなたがしていることは、言い換えれば、2つの異なるクラスを新しいフラットクラスに集約することだけです。私はforeachループの必要性を取り除くLINQサンプル#2を使用します。 – EtherDragon

0

レコードセットが並べ替えられた順序で値を返す場合。

値キー

'val' | 1

'val2' | 2

'val2' | 3

'val2' | 4

次に、ソート/マージ結合を行う場合があります。ここでの擬似コードは

while (!endofRecordset || !endofMyCollection) do 
    if (recorset[rIndex].Key==myList[lIndex].Key) 
     Join(recorset[rIndex], myList[lIndex]) 
    else if (recordset[rIndex] > myList[lIndex]) 
     lIndex++ 
    else 
     rIndex++ 
end while 

ですEDIT:

ここでは、C#

+0

いいえ、ソートされません:(。 – Metallicraft

関連する問題