2016-03-31 5 views
2

Ich habe zwei Produktlisten: Produkte und extraProducts Mein Ziel ist es, die 2 Listen zusammenzuführen, aber Duplikate nur basierend auf der ID zu vermeiden.2 Listen mit linq basierend auf eindeutiger ID zu vermischen, um Duplikate zu vermeiden

Hier ist mein bester Versuch:

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

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

aber es funktioniert nicht, weil es sein muss, wo nicht enthält.

Antwort

1

Sie könnten die Union Anweisung mit einem IEqualityComparer verwenden.

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

Union zu nutzen, können Sie Folgendes tun:

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

Es gibt auch Beispiele in der Dokumentation am unteren Rand der Seite.

+0

Ich bin bewusst, dass ich dies tun können, aber da Id ist das einzige, was ich verwende, um zu vergleichen, gibt es einen anderen Weg? Ich fühle mich einfach wie IEqualityComparer in diesem Fall ist Overkill. –

+0

Ich verstehe, dass es etwas zu viel ist, eine Klasse dafür zu machen, eine einfache Funktion wäre genug. Aber die Verwendung eines 'Where' kombiniert mit' Contains' macht die Komplexität größer und macht den Algorithmus langsamer. – Marnix

+0

Also habe ich beschlossen, IEqualityComparer auf meinem Produkt-Objekt zu implementieren, genau wie die Dokumentation, die Sie mir gegeben haben. Dies liegt daran, dass ich erkannt habe, dass ich mehr als nur die ID überprüfen muss, um sie zu vergleichen. Nun, da dies getan ist, wie verwende ich Union? –

3

Zunächst einmal schaffen eine IComparer-Klasse,

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

Dann Distinct() verwenden, nach zwei Listen verketten.

+0

Stattdessen habe ich IEqualityComparer in meinem Produktmodell implementiert. Wie würde ich den Unterschied oder die Vereinigung auf diese Weise machen? –

0

Eigentlich ist Union das beste hier. Und es gibt Distinct Funktion können Sie:

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

Dies sollte Vereinigung Sie zwei Listen in ein, ohne auf gleiche Elemente durch Id Eigenschaft.

1

Dies sollte Ihnen helfen - Es ist eine Konsolenanwendung ...

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; 
     } 
    } 
} 

Das sieht wie ein nützlicher Link für Sie als auch - http://www.elevenwinds.com/blog/linq-distinctby-with-lambda-expression-parameter/

+0

Was mache ich, damit mein Produktmodell IEqualityComparer bereits implementiert? –

+0

Odd Design-Wahl - denke Single Verantwortung ... Sie könnten nur eine neue Instanz des Produkts anstelle der EqualityComparer übergeben, aber das ist hacky ... Ich würde wieder auf Ihr Design schauen. –

Verwandte Themen