2010-10-27 6 views
107

J'ai Citez deux listes que j'ai besoin de combiner et la suppression des doublons des deux listescomment fusionner 2 Liste <T> avec la suppression des doublons en C#

Un peu difficile à expliquer, alors laissez-moi montrer un exemple de ce que le code ressemble, et ce que je veux en conséquence, dans l'exemple j'utilise le type int pas la classe ResultAnalysisFileSql.

first_list = [1, 12, 12, 5]

second_list = [12, 5, 7, 9, 1]

Le résultat de la combinaison des deux listes devrait aboutir à cette liste: result_list = [1, 12, 5, 7, 9]

Vous remarquerez que le résultat a la première liste, y compris ses deux valeurs "12", et dans second_list a une valeur supplémentaire de 12, 1 et 5.

classe ResultAnalysisFileSql

[Serializable] 
    public partial class ResultAnalysisFileSql 
    { 
     public string FileSql { get; set; } 

     public string PathFileSql { get; set; } 

     public List<ErrorAnalysisSql> Errors { get; set; } 

     public List<WarningAnalysisSql> Warnings{ get; set; } 

     public ResultAnalysisFileSql() 
     { 

     } 

     public ResultAnalysisFileSql(string fileSql) 
     { 
      if (string.IsNullOrEmpty(fileSql) 
       || fileSql.Trim().Length == 0) 
      { 
       throw new ArgumentNullException("fileSql", "fileSql is null"); 
      } 

      if (!fileSql.EndsWith(Utility.ExtensionFicherosErrorYWarning)) 
      { 
       throw new ArgumentOutOfRangeException("fileSql", "Ruta de fichero Sql no tiene extensión " + Utility.ExtensionFicherosErrorYWarning); 
      } 

      PathFileSql = fileSql; 
      FileSql = ObtenerNombreFicheroSql(fileSql); 
      Errors = new List<ErrorAnalysisSql>(); 
      Warnings= new List<WarningAnalysisSql>(); 
     } 

     private string ObtenerNombreFicheroSql(string fileSql) 
     { 
      var f = Path.GetFileName(fileSql); 
      return f.Substring(0, f.IndexOf(Utility.ExtensionFicherosErrorYWarning)); 
     } 


     public override bool Equals(object obj) 
     { 
      if (obj == null) 
       return false; 
      if (!(obj is ResultAnalysisFileSql)) 
       return false; 

      var t = obj as ResultAnalysisFileSql; 
      return t.FileSql== this.FileSql 
       && t.PathFileSql == this.PathFileSql 
       && t.Errors.Count == this.Errors.Count 
       && t.Warnings.Count == this.Warnings.Count; 
     } 


    } 

Tout exemple de code pour combiner et la suppression des doublons?

Répondre

203

Avez-vous eu un coup d'œil à Enumerable.Union

Cette méthode exclut les doublons du retour qu'elle. Ce comportement est différent de à la méthode Concat , qui renvoie tous les éléments dans les séquences d'entrée, y compris les doublons .

List<int> list1 = new List<int> { 1, 12, 12, 5}; 
List<int> list2 = new List<int> { 12, 5, 7, 9, 1 }; 
List<int> ulist = list1.Union(list2).ToList(); 
+1

lorsque j'utilise 'Collection ' ne fonctionne pas et juste en passant tous les éléments ... –

+5

@Dr TJ: Votre personne classe implémente IEqualityComparer ? Si c'est le cas, vous devrez vérifier vos méthodes GetHashCode et Equals. Voir la section Remarques de http://msdn.microsoft.com/en-us/library/bb341731.aspx. –

+1

Important à noter car j'ai rencontré des problèmes en utilisant cela sur 2 collections différentes: "Vous ne pouvez pas union deux types différents, sauf si l'un hérite de l'autre" de http://stackoverflow.com/a/6884940/410937 qui a donné un L'erreur "ne peut être déduite de l'utilisation". – atconway

22

pourquoi ne pas simplement par exemple

var newList = list1.Union(list2)/*.Distinct()*//*.ToList()*/; 

oh ... selon msdn vous pouvez laisser le .Distinct()

Cette méthode exclut les doublons de le retour qu'elle

12

Union Utilisons Linq:

using System.Linq; 
var l1 = new List<int>() { 1,2,3,4,5 }; 
var l2 = new List<int>() { 3,5,6,7,8 }; 
var l3 = l1.Union(l2).ToList(); 
10
List<int> first_list = new List<int>() { 
     1, 
     12, 
     12, 
     5 
    }; 

    List<int> second_list = new List<int>() { 
     12, 
     5, 
     7, 
     9, 
     1 
    }; 

    var result = first_list.Union(second_list); 
+1

Vous n'avez pas besoin d'appeler Distinct, lisez la documentation http://msdn.microsoft.com/fr-fr/library/bb341731.aspx, ou testez-le vous-même ... –

16
Union

n'a pas de bonnes performances: ce article Décrivez les comparer avec ensemble

var dict = list2.ToDictionary(p => p.Number); 
foreach (var person in list1) 
{ 
     dict[person.Number] = person; 
} 
var merged = dict.Values.ToList(); 

Listes et LINQ fusion: 4820ms
Dictionnaire fusion: 16ms
HashSet et IEqualityComparer: 20ms
LINQ Union et IEqualityComparer: 24ms

+0

Un autre avantage de l'utilisation d'une fusion de dictionnaire - > J'ai deux listes qui reviennent des données DB. Et mes données ont un champ d'horodatage, qui est différent dans les deux listes de données. Avec l'union je reçois des doublons en raison de l'horodatage étant différent. Mais avec la fusion je peux décider quel champ unique je veux considérer dans le dictionnaire. +1 – JimSan

+0

Peut varier en fonction de la vitesse du processeur, dépend du type de processeur que vous avez. –

+2

Et à la fin de l'article il est dit: "Je préfère LINQ Union parce qu'elle communique l'intention très clairement." ;) (aussi, il n'y avait qu'une différence de 8 ms) –

Questions connexes