2010-10-27 135 views
107

que tienen una lista de dos listas que necesito para combinar y eliminar valores duplicados de las dos listascómo combinar 2 Lista <T> con la eliminación de valores duplicados en C#

un poco difícil de explicar, así que voy a mostrar un ejemplo de lo el código parece, y lo que quiero como resultado, en la muestra que uso int tipo no ResultAnalysisFileSql clase.

first_list = [1, 12, 12, 5]

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

El resultado de la combinación de las dos listas debería resultar en esta lista: lista_resultado = [1, 12, 5, 7, 9]

Observará que el resultado tiene la primera lista, incluidos sus dos valores "12", y en la segunda lista tiene un valor 12, 1 y 5 adicional.

clase ResultAnalysisFileSql código

[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; 
     } 


    } 

Cualquier muestra para combinar y eliminar los duplicados?

Respuesta

203

¿Ha tenido un vistazo a Enumerable.Union

Este método excluye los duplicados de la devolución establecen. Este es el comportamiento diferente de con el método Concat , que devuelve todos los elementos en las secuencias de entrada que incluyen duplicados.

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

cuando uso 'Colección ' no funciona y simplemente pasa todos los elementos ... –

+5

@Dr TJ: ¿Su clase implementa IEqualityComparer ? Si es así, deberás verificar tus métodos GetHashCode e Igual. Consulte la sección Comentarios de http://msdn.microsoft.com/en-us/library/bb341731.aspx. –

+1

Es importante tener en cuenta porque me encontré con problemas al usar esto en 2 colecciones diferentes: "No se pueden unir dos tipos diferentes, a menos que uno herede de la otra" de http://stackoverflow.com/a/6884940/410937, que dio como resultado un 'no se puede deducir del error de uso'. – atconway

22

por qué no simplemente por ejemplo

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

oh ... según msdn se puede dejar de lado el .Distinct()

Este método excluye los duplicados de el retorno ajustado

12

Unión de utilizar 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

No es necesario que llame a Distinct, lea la documentación http://msdn.microsoft.com/en-us/library/bb341731.aspx, o pruébela usted mismo ... –

16

Unión no tiene un buen rendimiento: este article describir acerca de ellos se compara con juntas

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

listas y LINQ Merge: 4820ms
Diccionario de fusión: 16 ms
HashSet and IEqualityComparer: 20ms
LINQ Union and IEqualityComparer: 24ms

+0

También otra ventaja de usar una combinación de diccionario - > Tengo dos listas que vuelven de los datos de la base de datos. Y mis datos tienen un campo de marca de tiempo, que es diferente en las dos listas de datos. Con la unión obtengo duplicados debido a que la marca de tiempo es diferente. Pero con la fusión puedo decidir qué campo único quiero considerar en el diccionario. +1 – JimSan

+0

Puede variar según la velocidad del procesador, depende del tipo de CPU que tenga. –

+2

Y al final del artículo dice: "Prefiero LINQ Union porque comunica intenciones muy claramente". ;) (también, solo había una diferencia de 8 ms) –

Cuestiones relacionadas