2010-10-27 11 views
107

Mam dwie listy List że muszę połączyć i usuwania zduplikowanych wartości obu listachjak połączyć 2 List <T> z usuwania zduplikowanych wartości w C#

trochę trudne do wyjaśnienia, więc pozwól mi pokazać przykład co kod wygląda, a czego chcę w rezultacie, w przykładzie używam klasy int nie ResultAnalysisFileSql.

first_list = [1, 12, 12, 5]

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

wynikiem połączenia dwóch list powinno prowadzić do tej listy: Result_list = [1, 12, 5, 7, 9]

Zauważysz, że wynik ma pierwszą listę, w tym dwie "12" wartości, a na drugiej liście ma dodatkową wartość 12, 1 i 5.

klasa ResultAnalysisFileSql kod

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


    } 

Każda próbka do łączenia i usuwania duplikatów?

Odpowiedz

203

Miałeś spojrzeć na Enumerable.Union

Ta metoda wyklucza duplikaty z powrotem ustawić. Jest to inne zachowanie dla metody Concat , która zwraca wszystkie elementy w sekwencjach wejściowych, w tym duplikatach .

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

kiedy używam 'Kolekcja ' nie działa i po prostu przekazuje wszystkie przedmioty ... –

+5

@Dr TJ: Czy twoja osoba Klasa implementuje IEqualityComparer ? Jeśli tak, musisz sprawdzić metody GetHashCode i Equals. Zobacz sekcję Spostrzeżenia na stronie http://msdn.microsoft.com/en-us/library/bb341731.aspx. –

+1

Ważne, aby zauważyć, ponieważ napotkałem problemy z korzystaniem z tego w 2 różnych kolekcjach: "Nie można łączyć dwóch różnych typów, chyba że jeden dziedziczy z drugiego" z http://stackoverflow.com/a/6884940/410937, co dało 'nie można wywnioskować z błędu użycia. – atconway

22

dlaczego nie po prostu np

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

oh ... według msdn można pominąć .Distinct()

Ta metoda wyklucza duplikaty z powrót ustawić

12

używać LINQ w Unii:

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

Nie musisz dzwonić do Distinct, przeczytaj dokumentację http://msdn.microsoft.com/en-us/library/bb341731.aspx lub przetestuj go sam ... –

16

Unia nie dobre osiągi: to article opisać o porównanie ich razem

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

listami i LINQ scalić: 4820ms
słownik seryjnej: 16ms
HashSet i IEqualityComparer: 20ms
LINQ Union i IEqualityComparer: 24ms

+0

Kolejna korzyść z używania fuzji ze słownikami - > Mam dwie listy wracające z danych DB. A moje dane mają pole znacznika czasu, które różni się na dwóch listach danych. Wraz ze związkiem otrzymuję duplikaty, ponieważ znacznik czasu jest inny. Ale dzięki scaleniu mogę zdecydować, które unikalne pole chcę rozważyć w słowniku. +1 – JimSan

+0

Może się różnić w zależności od szybkości procesora, zależy od tego, jaki masz procesor. –

+2

Na końcu artykułu jest napisane: "Wolę LINQ Union, ponieważ komunikuje się bardzo wyraźnie". ;) (również, była tylko różnica 8 ms) –

Powiązane problemy