2011-07-30 9 views
2

大きなセットの複数の値を保存して、一意でない値を持つプロパティに基づいてラムダ式で素早く見つけることができますか?プロパティに基づいて、セットから要素を素早く選択

サンプルケース(パフォーマンスのために最適化されていない):

class Product 
{ 
    public string Title { get; set; } 
    public int Price { get; set; } 
    public string Description { get; set; } 
} 

IList<Product> products = this.LoadProducts(); 

var q1 = products.Where(c => c.Title == "Hello"); // 1 product. 
var q2 = products.Where(c => c.Title == "Sample"); // 5 products. 
var q3 = products.Where(c => string.IsNullOrEmpty(c.Title)); // 12 345 products. 

タイトルがユニークだった場合、IDictionaryまたはHashSetを使用してパフォーマンスを最適化するのは簡単だろう。しかし、値が一意でない場合はどうですか?

+0

'Title'にソートされたバイナリ検索ツリーかもしれません(検索する必要のある唯一のプロパティであれば) – Magnus

+0

最後のクエリはコンパイルされません。 'string.IsNullOrEmpty(c.Title)'を意味しましたか? – svick

+0

@スウィック:変更されました。ありがとうございました。 –

答えて

2

最も簡単な解決策は、Productというコレクションの辞書を使用することです。最も簡単には

var products = this.LoadProducts().ToLookup(p => p.Title); 

var example1 = products["Hello"]; // 1 product 
var example2 = products["Sample"]; // 5 products 

を使用するためにあなたの第三の例は少し難しいですが、あなたはそのためのApplyResultSelector()を使用することができます。

2

LINQでインデックス付きクエリを実行する機能が必要です。彼らのウェブサイトから

http://i4o.codeplex.com/

i4o(オブジェクトのインデックス)(私たちはSQLで行うのと同じ)

は明らかにあなたの問題を解決することができi4oと呼ばれるライブラリがありますLINQ を拡張してオブジェクトにインデックスを付けることができるファーストクラスのライブラリです。 i4oを使用すると、 のLINQ操作の速度は、多くの場合、i4oが の場合よりも1000倍以上高速です。

i4oは、開発者が任意のクラスのための IndexSpecificationを指定することができ、その後、 は、LINQの操作を行うとき は、むしろ順次検索よりも、インデックス指定を使用することを、そのクラスのコレクションを実装するために IndexableCollectionを使用して動作しますインデックス作成の恩恵を受けることができます。

も以下はi4oを使用する方法の例を提供します。

http://www.hookedonlinq.com/i4o.ashx

は、それは短くしてください以下を行う必要があります。

  1. あなた」に[スローアウェイチップ()]属性を追加します。タイトル "プロパティ
  2. IndexableCollection <Product>をデータソースとして使用します。
  3. この時点から、インデックス可能フィールドを使用するすべてのlinqクエリは、インデックスを使用するクエリのmagnituideパフォーマンスの増加の結果、順次検索を実行するのではなくインデックスを使用します。
+0

+1ニース。この図書館で良い経験をしたことがありますか? – sgtz

+0

まだ私はまだプロダクションで使っていませんが、楽しみにしています。 –

関連する問題