J'ai la situation suivante
class Person
{
string Name;
int Value;
int Change;
}
List<Person> list1;
List<Person> list2;
Je dois combiner les 2 listes en une nouvelle List<Person>
au cas où ce serait la même personne que l'enregistrement de combinaison aurait ce nom, la valeur de la personne dans list2, le changement serait la valeur de list2 - la valeur de list1. Le changement est égal à 0 s'il n'y a pas de doublon
Réponses:
Cela peut facilement être fait en utilisant la méthode d'extension Linq Union. Par exemple:
Cela renverra une liste dans laquelle les deux listes sont fusionnées et les doubles sont supprimés. Si vous ne spécifiez pas de comparateur dans la méthode d'extension Union comme dans mon exemple, il utilisera les méthodes Equals et GetHashCode par défaut dans votre classe Person. Si, par exemple, vous souhaitez comparer des personnes en comparant leur propriété Name, vous devez remplacer ces méthodes pour effectuer la comparaison vous-même. Consultez l'exemple de code suivant pour ce faire. Vous devez ajouter ce code à votre classe Person.
Si vous ne souhaitez pas définir la méthode Equals par défaut de votre classe Person pour toujours utiliser le Name pour comparer deux objets, vous pouvez également écrire une classe de comparateur qui utilise l'interface IEqualityComparer. Vous pouvez ensuite fournir ce comparateur comme deuxième paramètre dans la méthode Union d'extension Linq. Vous trouverez plus d'informations sur l'écriture d'une telle méthode de comparaison sur http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx
la source
Union
avecIntersect
?Concat
qui ne fusionne pas les doublonsJ'ai remarqué que cette question n'était pas marquée comme réponse après 2 ans - je pense que la réponse la plus proche est Richards, mais elle peut être beaucoup simplifiée à ceci:
Bien que ce ne soit pas une erreur dans le cas où vous avez des noms en double dans l'un ou l'autre ensemble.
Certaines autres réponses ont suggéré d'utiliser l'union - ce n'est certainement pas la voie à suivre car cela ne vous donnera qu'une liste distincte, sans faire la combinaison.
la source
Pourquoi vous n'utilisez pas seulement
Concat
?Concat fait partie de linq et est plus efficace que de faire un
AddRange()
dans ton cas:
la source
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!
C'est mon point.C'est Linq
C'est normal (AddRange)
C'est normal (Foreach)
C'est normal (Foreach-Dublice)
la source
Il y a quelques éléments à faire, en supposant que chaque liste ne contient pas de doublons, que le nom est un identifiant unique et qu'aucune des deux listes n'est ordonnée.
Commencez par créer une méthode d'extension d'ajout pour obtenir une seule liste:
Ainsi peut obtenir une seule liste:
Puis groupe sur le nom
Puis peut traiter chaque groupe avec un assistant pour traiter un groupe à la fois
Qui peut être appliqué à chaque élément de
grouped
:(Attention: non testé.)
la source
Append
est une copie presque exacte du prêt à l'emploiConcat
.Enumerable.Concat
et à le réimplémenter .Vous avez besoin de quelque chose comme une jointure externe complète. System.Linq.Enumerable n'a pas de méthode qui implémente une jointure externe complète, nous devons donc le faire nous-mêmes.
la source
Le code suivant fonctionne-t-il pour votre problème? J'ai utilisé un foreach avec un peu de linq à l'intérieur pour combiner des listes et j'ai supposé que les gens sont égaux si leurs noms correspondent, et il semble imprimer les valeurs attendues lors de l'exécution. Resharper n'offre aucune suggestion pour convertir le foreach en linq, c'est donc probablement aussi bien que cela peut être fait de cette façon.
la source
la source