2016-04-25 10 views
2

は、私は私のC#プログラムで次のように定義されたクラスがあるとします。のLINQ - ><リストで欠損値を探す - ひどく非効率的な

class MyClass 
{ 
    public string ID; 
    public int Val; 
    public DateTime StartDate; 
    public DateTime EndDate; 
} 

をそして、私は私のプログラムでは、巨大なList<MyClass>を持っていると私は確認する必要がありますすべての値がこのリストにある場合はここで

  1. 基準の特定のセットが
  2. (この単純化した例では、Val != 0を想定するが、基準は、実質的に、より複雑なものよりもある)が満たされている対応する値でありますこの電流値のEndDate

私の現在のコードに等しいStartDateとリスト(IDの試合)で、次のとおりです。このコードは動作します

var myTest = new List<MyClass>(); 

... populate myTest ... 

var expectDt1 = myTest 
        .Where(v => v.Val != 0) 
        .Select(v => new {ID = v.ID, EndDate = v.EndDate}); 

var dontExist = expectDt1 
        .Where(tst => 
         !myTest.Any(v => 
          v.ID.Equals(tst.ID) 
          && v.StartDate == tst.EndDate 
          ) 
         ); 

を、それが徐々にひどく実行している(私のリストには、多くを持っています何千ものエントリ)。これをより効率的にする(グループ化するなど)これを行うより良い方法がありますか?

(PS - 私はこれを中間のexpectedDt1変数を必要とせずに簡略化したLinqステートメントにすることができますが、それは効率を助長しませんでしたので、私は単にこれを

+0

おそらくあなたは、このための悪いデータ構造をchosed。いくつのレコードが存在するか、hom = 0、繰り返しIDの数などについての詳細を教えてください。 –

+1

私は 'Dictionary >'にリストを詰め込みます。ここで、外側のキーはStartDateです。次に、正しい開始日とTryGetValue()のIDを取得するたびに、すべてのIDを取得します。これはもちろん、セットアップには時間がかかりますが、冗長性はありません。 (実際には心配しないでください - これは、以下の彼の答えでServyが提案したものの、あとでToLookupについて聞いたことのないものです。 –

+2

@EdPlunkett複数のパラメータを持つキーで1つの辞書を使用すると、(時間と空間の両方で)かなり効率的です。そして 'ILookup'(これは' Dictionary'と非常に似た構造です)を使うと、キーの重複値をサポートするという点でコードをもっときれいにすることができ、存在しないキーを多く渡すことができます – Servy

答えて

6

ハッシュベースのルックアップ構造を作成して、単一のアイテムごとに大きなリストを使用して線形検索を行うのではなく、指定した値でアイテムを検索したいと思うでしょう。

var lookup = myTest.Where(ItemIsValid) 
    .ToLookup(item => new 
    { 
     item.ID, 
     Date = item.EndDate, 
    }); 

は、その後、あなたがルックアップで一致を見つけることができるかどうかを確認するために、あなたの他のコレクションを経由して取得:

var query = expectDt1.Where(item => !lookup[new {item.ID, Date = item.StartDate}].Any()); 
+0

今、それを試してみて、感謝、Servy! –

+0

それは** SUPER **高速!!! - ありがとうSOOO MUCH !!!! –

関連する問題