2011-03-28 17 views
28

私は2つのリストを持っています。 1は製品群です。もう1つは、店内の商品のコレクションです。LINQ:別のリストの名前(文字列)と一致するリスト内の項目を返しますか?

名前が製品の名前と一致する場合、すべてのshopProductsを返すことができる必要があります。

私はこれを持っていますが、動作していないようです。何か案は?

私は本当に他のリストに名前が存在するすべてのショップ製品を教えてください。

すべてのヘルプは本当にlistOfProductsは、多くの項目が含まれている場合、あなたがより良いパフォーマンスを得るかもしれない、

var products = shopProducts.Where(m=> listOfProducts.Select(l=>l.Name).ToList().Contains(m=>m.Name)); 
+0

コメントありがとうございました!私はそれを今働いている...もう一度ありがとう..答えが受け入れられました。 – Martin

答えて

61
var products = shopProducts.Where(p => listOfProducts.Any(l => p.Name == l.Name)) 
          .ToList(); 

LINQツーオブジェクトのためにこれをしてください試してみてください

おかげ

+0

linqが対処するための素晴らしいトリックです。 – mavnn

+0

ありがとうございます。本当に役に立ちました。 – ajexpress

1

を高く評価必要なすべての名前を含むHashSet<T>を作成し、それをq uery。 HashSet<T>は、任意のIEnumerable<T>に対してO(n)と比較してO(1)ルックアップ性能を持ちます。

var names = new HashSet<string>(listOfProducts.Select(p => p.Name)); 
var products = shopProducts.Where(p => names.Contains(p.Name)) 
          .ToList(); 

LINQツーSQLのために、私は(希望?)プロバイダは、クエリの手動調整が必要とすることなく、自動的に生成されたSQLを最適化することができることを期待します。

1
var products = shopProducts 
     .Where(shopProduct => 
       listOfProducts.Any(p => shopProduct.Name == p.Name)) 
     .ToList(); 
10

次の例のように、結合を使用できます。参加の

var q = from sp in shopProducts 
     join p in listOfProducts on sp.Name equals p.Name 
     select sp; 

充実したガイドがhereです。

+0

私は '特別な' linq構文が嫌いですが、概念的にはjoinはおそらくlinq-to-sqlを使う方法です。オブジェクトにlinqを使用すると、どちらが優れているかはわかりません。 – mavnn

+0

linq-to-objectについて - この回答のクエリは最終的に、ドキュメントによればhashed-lookup.http://msdn.microsoft.com/en-us/library/bb534675というEnumerable.Join呼び出しに変換されます。 .aspx - "デフォルトの等価比較ツールDefaultは、キーのハッシュと比較に使用されます。" – devgeezer

4

同じ名前の製品が等しいことを示すIEqualityComparer<T>を作成できます。

class ProductNameEqulity : IEqualityComparer<Product> 
{ 
    public bool Equals(Product p1, Product p2) 
    { 
     return p1.Name == p2.Name 
    } 

    public int GetHashCode(Product product) 
    { 
     return product.Name.GetHashCode(); 
    } 
} 

これはIntersect拡張メソッドで使用できます。

var products = shopProducts.Intersect(listOfProducts, new ProductNameEquality()); 
+0

このアプローチは私の投票を得る。 –

関連する問題