2016-12-24 5 views
0

Ich habe zwei List<CustomObject>, genannt list1 und list2schnellste Weg, um zwei Liste zu vergleichen <CustomObject>

public class CustomObject 
{ 
    public string foo { get; set; } 
    public string bar{ get; set; } 
} 

Das Ziel ist es, eine neue Liste mit allen Einträgen zu erzeugen, die in list2 geändert/hinzugefügt wurden.

Da diese Listen ziemlich lang werden, durch sie Looping ist keine Option ...

Irgendwelche Ideen?

+0

Müssen Sie nur Objektinstanzen vergleichen, oder müssen Sie einen tiefen Vergleich aller Eigenschaften durchführen? –

+0

Ich muss nur den Wert von foo jedes Listeneintrags vergleichen. Ich schätze das zählt dann als tiefvergleich? – CiriousJoker

+0

Ist list1 deine ursprüngliche Liste und list2 ist die aktuelle Liste nach Änderungen und so? Wenn Sie wirklich nachverfolgen möchten, was sich innerhalb einer Liste im Laufe der Zeit geändert hat, ist das eine ganz andere Frage (und eine, die eine einfachere Antwort hat, als zwei Listen zu vergleichen). – PMV

Antwort

1

eine andere Antwort Hinzufügen einige zusätzliche NFRs zu empfangen, die in den Kommentaren gekommen sind:

  1. Objekte können durch einen Hash-Code
  2. identifiziert werden
  3. Die Liste ist sehr groß, so dass die Leistung ein Problem ist
  4. Die Idee ist es, eine alte Liste mit einer neuen Liste zu vergleichen, um zu sehen, ob neue Hash-Codes aufgetaucht sind.

Sie Ihre Objekte in einem Wörterbuch gespeichert werden soll:

var list = new Dictionary<string, CustomObject>(); 

Wenn Sie sie hinzufügen, den Hash als Schlüssel zur Verfügung stellen:

list.Add(customObject.Hash, customObject); 

für neue zu scannen:

var difference = new List<CustomObject>(); 
foreach (customObject o in newList) 
{ 
    if (oldList.ContainsKey(o.Hash)) difference.Add(o); 
} 
Log(String.Format("{0} new hashes found.", difference.Count)); 

Mit dem Dictionary nutzen Sie den Weg t Die Schlüssel werden in einer Hash-Tabelle gespeichert. Ein Element in einer Hash-Tabelle zu finden ist schneller als nur einen Scan & zu vergleichen Art der Sache. Ich glaube, das wird O (n * log (n)) anstelle von O (n^2) sein.

1

Hier ist eine traditionelle Art und Weise, es zu tun:

public class CustomObject : IComparable 
{ 
    public string foo { get; set; } 
    public string bar{ get; set; } 
    public int CompareTo(CustomObject o) 
    { 
     if (this.foo == o.foo && this.bar == o.bar) return 0; 

     //We have to code for the <and> comparisons too. Could get painful if there are a lot of properties to compare. 
     if (this.Foo == o.Foo) return (this.Bar.CompareTo(o.Bar)); 
     return this.Foo.CompareTo(o.Foo); 
    } 
} 

Dann Linq.Except verwenden:

listA.Except(listB) 
+0

Darf ich fragen, warum CompareTo einen int zurückgeben muss?Ich fand [das] (https://msdn.microsoft.com/en-us/library/system.icomparable.compareto (v = vs.110) .aspx), aber ich bekomme nicht, wie -1, 0 zurückkommt und 1 ändert alles. Derzeit erzeugt dies immer eine "kann Bool nicht in Int-Fehler konvertieren" – CiriousJoker

+0

Hoppla vergessen, dass Detail. Bearbeitet. –

+0

Ooh, jetzt macht es Sinn, völlig missverstanden, dass die Dokumentation – CiriousJoker

Verwandte Themen