Ich habe die folgende Situation
class Person
{
string Name;
int Value;
int Change;
}
List<Person> list1;
List<Person> list2;
Ich muss die 2 Listen zu einer neuen kombinieren, List<Person>
falls es dieselbe Person ist, die der Kombinationsdatensatz diesen Namen haben würde, Wert der Person in Liste2, Änderung wäre der Wert von Liste2 - der Wert von Liste1. Änderung ist 0, wenn kein Duplikat vorhanden ist
Antworten:
Dies kann einfach mit der Linq-Erweiterungsmethode Union erfolgen. Beispielsweise:
Dies gibt eine Liste zurück, in der die beiden Listen zusammengeführt und Doppel entfernt werden. Wenn Sie in der Union-Erweiterungsmethode keinen Vergleicher wie in meinem Beispiel angeben, werden die Standardmethoden Equals und GetHashCode in Ihrer Person-Klasse verwendet. Wenn Sie beispielsweise Personen durch Vergleichen ihrer Name-Eigenschaft vergleichen möchten, müssen Sie diese Methoden überschreiben, um den Vergleich selbst durchzuführen. Überprüfen Sie dazu das folgende Codebeispiel. Sie müssen diesen Code Ihrer Personenklasse hinzufügen.
Wenn Sie nicht festlegen möchten, dass die Standardmethode Equals Ihrer Person-Klasse immer den Namen zum Vergleichen von zwei Objekten verwendet, können Sie auch eine Vergleichsklasse schreiben, die die IEqualityComparer-Schnittstelle verwendet. Sie können diesen Vergleicher dann als zweiten Parameter in der Linq-Erweiterungs-Union-Methode angeben. Weitere Informationen zum Schreiben einer solchen Vergleichsmethode finden Sie unter http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx
quelle
Union
mitIntersect
?Concat
keine DuplikateIch habe festgestellt, dass diese Frage nach 2 Jahren nicht als beantwortet markiert wurde. Ich denke, die nächste Antwort ist Richards, aber sie kann erheblich vereinfacht werden:
Obwohl dies kein Fehler sein wird , wenn Sie in beiden Sätzen doppelte Namen haben.
Einige andere Antworten haben vorgeschlagen, Unioning zu verwenden - dies ist definitiv nicht der richtige Weg, da Sie nur eine eindeutige Liste erhalten, ohne die Kombination durchzuführen.
quelle
Warum benutzt du nicht einfach
Concat
?Concat ist ein Teil von linq und effizienter als ein
AddRange()
in deinem Fall:
quelle
Actually, due to deferred execution, using Concat would likely be faster because it avoids object allocation - Concat doesn't copy anything, it just creates links between the lists so when enumerating and you reach the end of one it transparently takes you to the start of the next!
Dies ist mein Punkt.Das ist Linq
Dies ist Normal (AddRange)
Dies ist Normal (Foreach)
Dies ist normal (Foreach-Dublice)
quelle
Dies erfordert einige Schritte, vorausgesetzt, jede Liste enthält keine Duplikate, Name ist eine eindeutige Kennung und keine der beiden Listen ist geordnet.
Erstellen Sie zunächst eine Append-Erweiterungsmethode, um eine einzelne Liste zu erhalten:
Somit kann eine einzelne Liste erhalten werden:
Dann gruppieren Sie nach Namen
Dann kann jede Gruppe mit einem Helfer verarbeitet werden, um jeweils eine Gruppe zu verarbeiten
Welche kann auf jedes Element angewendet werden von
grouped
:(Warnung: ungetestet.)
quelle
Append
sind ein fast genaues Duplikat des Out-of-the-BoxConcat
.Enumerable.Concat
und es daher neu implementiert.Sie benötigen so etwas wie eine vollständige äußere Verknüpfung. System.Linq.Enumerable hat keine Methode, die eine vollständige äußere Verknüpfung implementiert, daher müssen wir dies selbst tun.
quelle
Funktioniert der folgende Code für Ihr Problem? Ich habe ein foreach mit ein wenig Linq verwendet, um Listen zu kombinieren, und angenommen, dass die Leute gleich sind, wenn ihre Namen übereinstimmen, und es scheint, als würden die erwarteten Werte beim Ausführen ausgedruckt. Resharper bietet keine Vorschläge zur Konvertierung des foreach in linq an, daher ist dies wahrscheinlich so gut, wie es auf diese Weise möglich ist.
quelle
quelle