2012-11-21 21 views
8

enthält ich nur true zurück, ich versuche, wenn eine Liste einen der Name/Wert von list2 enthält:Überprüfen Sie, ob eine Liste alle Elemente aus einem anderen

Das wäre meine Struktur sein:

public class TStockFilterAttributes 
{ 
    public String Name { get; set; } 
    public String Value { get; set; } 
} 

List<TStockFilterAttributes> List1 = new List<TStockFilterAttributes>(); 
List<TStockFilterAttributes> List2 = new List<TStockFilterAttributes>(); 

Diese sollte true zurück:

List1.Add(new TStockFilterAttributes { Name = "Foo", Value = "Bar" }); 
List2.Add(new TStockFilterAttributes { Name = "Foo", Value = "Bar" }); 

Aber diese falsche zurückkehren würde, weil Namen & & Wert nicht übereinstimmen:

List1.Add(new TStockFilterAttributes { Name = "Foo", Value = "Bar" }); 
List2.Add(new TStockFilterAttributes { Name = "Foo", Value = "Foo" }); 

Jede Liste könnte viele verschiedene Werte enthalten und ich muss nur wissen, ob irgendeine von Liste1 mit einer in Liste2 übereinstimmt.

Ich habe versucht mit:

return List1.Intersect(List2).Any(); 

aber dies scheint in allen Fällen false zurück, ich gehe davon aus das ist, weil ich eine Klasse in List halte eher als eine einfache int/string?

+6

'Intersect' arbeitet auf Referenzen standardmäßig, da Sie ein neues Objekt jedes Mal erstellen, würden Sie Ihre eigenen schreiben [' IEqualityComparer '] (http://msdn.microsoft.com /en-us/library/ms132151.aspx) –

Antwort

7

Aufschalten Equals und GetHashCode Implementierung für die Klasse:

public class TStockFilterAttributes 
{ 
    public String Name { get; set; } 
    public String Value { get; set; } 

    public override bool Equals(object obj) 
    { 
     TStockFilterAttributes other = obj as TStockFilterAttributes; 
     if (obj == null) 
      return false; 

     return Name == obj.Name && Value == obj.Value; 
    } 

    public override int GetHashCode() 
    { 
     return Name.GetHashCode()^Value.GetHashCode(); 
    } 
} 

Oder einen Vergleich zu Intersect Funktion zur Verfügung stellen.

+0

Ich habe das gerade nach dem Stellen der Frage hier versucht und es hat funktioniert. Ich werde dies als die Antwort markieren, wenn ich erlaubt bin, da es meiner Lösung entspricht. Vielen Dank. – webnoob

+0

@webnoob Sie sind willkommen. Das Problem trat in den Standardimplementierungen "Equals" und "GetHashCode" auf, die Objektreferenzen verwenden, um verschiedene Objekte zu vergleichen. Und Linq verwendet diese Methoden zum Vergleich. –

5

Unter der Annahme, Leistung keine Rolle spielt:

List1.Any(l1 => List2.Any(l2 => l1.Key == l2.Key && l1.Value == l2.Value)); 

Alternativen wären Equals außer Kraft zu setzen oder ihn eine Struct zu machen (wahrscheinlich nicht geeignet)

+2

Leistung ist immer wichtig;) – webnoob

1

Das Problem hier ist, dass Sie Referenzen vergleichen und nicht Die Objekte. Da Sie jedes Mal ein neues Objekt erstellen, werden die Listen niemals dieselben Referenzen enthalten.

Versuchen:

var FooBar = new TStockFilterAttributes { Name = "Foo", Value = "Bar" }; 
var FooFoo = new TStockFilterAttributes { Name = "Foo", Value = "Foo" }; 
List1.Add(FooBar); 
List2.Add(FooBar); 
List2.Add(FooFoo); 
return List1.Intersect(List2); 
+0

Das ist, was ich dachte, das Problem war, ich habe jetzt ein IEqualityComparer implementiert, um das Problem zu sortieren. – webnoob

+0

Absolut. Je nachdem, was Sie benötigen, haben Sie zwei Ansätze. In den meisten Fällen möchten wir Referenzen überprüfen, aber manchmal müssen Sie nur die Werte vergleichen. – Pete

3
var query = List1.Where(x => List2.Exists(y => y.Name == x.Name && y.Value == x.Value)); 

Aber Leistung könnte

0

spät zu stoßen in schlecht sein, aber mit schneiden wir wählen können und vermeiden Gleichheit verwenden.

list1.Select(Function(p) p.ItemID).Intersect(list2.Select(Function(p)p.ItemID)).Any() 
Verwandte Themen