2016-03-31 10 views
2

私は2つの製品リストを持っています:productsとextraProducts 私の目標は2つのリストをマージします。重複を避けるために一意のIDに基づいて2つのリストをlinqでマージする

は、ここに私の最高の試みです:

List<Product> allProductsWithNoDuplicates = new List<Product>(); 

allProductsWithNoDuplicates.AddRange(products.Where(p => extraProducts.Select(ep => ep.Id).Contains(p.Id)).ToList()); 

しかし、それは含まれていませどこにする必要があるので、それは動作しません。

答えて

1

IEqualityComparerUnionステートメントを使用できます。

https://msdn.microsoft.com/en-us/library/bb358407%28v=vs.100%29.aspx

連合を使用するには、次の操作を行うことができます

List<Product> myUniqueProducts = products.Union(extraProducts, new ProductEqualityComparer()).ToList(); 

また、ページの下部にあるドキュメントに例を示します。すべての

+0

ですが、idので、私が比較するために使用している唯一のものは別の方法ですか?私はちょうどIEqualityComparerがこの場合には残虐であるように感じる。 –

+0

私はこのクラスを作るのが少し難しいと感じていますが、単純な関数で十分でしょう。しかし、 'Where'を' Contains'と組み合わせると複雑さが増し、アルゴリズムが遅くなります。 – Marnix

+0

私はあなたが私に与えたドキュメントのように、私のProductオブジェクトにIEqualityComparerを実装することに決めました。これは、私がIDを比較するだけではなく、それ以上をチェックする必要があることがわかったからです。今これでユニオンをどうやって使うのですか? –

3

まず、

public class ProductComparer: IComparer 
{ 
    int IComparer.Compare(object a, object b) 
{ 
    if(a.Id == b.Id) 
     return 0; 
    else 
    return 1; 
} 
} 

は次に、2つのリストを連結した後)(個別使用したIComparerクラスを作成します。

allProductsWithNoDuplicates = products.Concat(extraProducts).Distinct(new ProductComparer()).ToList(); 
+0

代わりに私の製品モデルでIEqualityComparerを実装しました。このようにして、私はどのようにして別個の組合を行うのでしょうか? –

0

実際にはUnionが最適です。 同上プロパティによって、同じ要素なしなし1で

var allProductsWithNoDuplicates = products.Union(extraProducts).DistinctBy(x => x.Id); 

これがすべき組合あなた二つのリスト:そして、あなたが使用することができますDistinct機能があります。

1

これはあなたを助ける必要があります - それは、コンソールアプリケーションです...

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace SO 
{ 
    class Program 
    { 
     public static void Main(string[] args) 
     { 
      var listA = new List<Product>(); 

      var listB = new List<Product>(); 

      listA.Add(new Product() {Id = 1, Name = "Hair Curling Tongs"}); 
      listA.Add(new Product() {Id = 2, Name = "Toys"}); 
      listA.Add(new Product() {Id = 3, Name = "Coffee"}); 

      listB.Add(new Product() {Id = 3, Name = "Dress"}); 
      listB.Add(new Product() {Id = 4, Name = "Handbag"}); 

      var results = listA.Union(listB).Distinct(new EqualityComparer()).ToList(); 

      foreach(var result in results) 
      { 
       Console.WriteLine("{0} ----- {1}", result.Id, result.Name); 
      } 

      // TODO: Implement Functionality Here 

      Console.Write("Press any key to continue . . . "); 
      Console.ReadKey(true); 
     } 
    } 

    class Product{ 
     public int Id{get; set;} 
     public string Name {get; set;} 
    } 

    class EqualityComparer: IEqualityComparer<Product> { 

     public bool Equals(Product p1, Product p2) { 
      return p1.Id == p2.Id; 
     } 

     public int GetHashCode(Product p){ 
      return p.Id; 
     } 
    } 
} 

これは同様にあなたのための有用なリンクのように見える - 私はこれを行うことができます知っていますhttp://www.elevenwinds.com/blog/linq-distinctby-with-lambda-expression-parameter/

+0

私の製品モデルは既にIEqualityComparerを実装していますか? –

+0

奇妙なデザインの選択 - 考える単一の責任... EqualityComparerの代わりに新しい製品のインスタンスを渡すことができますが、それはハッキーです...私はあなたのデザインを再度見ていきます。 –

関連する問題