2012-04-03 23 views
0

Ich muss eine Liste basierend auf zwei anderen Listen erstellen. Aber es scheint, als ob die Duplikate nicht entfernt werden.Zusammenführen von zwei Listen ohne Duplikate

Ist dies eine effiziente Methode zum Zusammenführen zweier Listen ohne Duplikate?

List<String[]> blocksComparisonSet1 = new List<String[]>(); 
List<String[]> blocksComparisonSet2 = new List<String[]>(); 
//we will combine list1 and list2 into this one 
List<String[]> blocksComparisonFinal = new List<String[]>(); 

//this is how I store data in each list 
//if both values found, add both of them (partial functions, FYI) 
String[] NA = new String[2]; //keep results 
NA[0] = baseLine; //[0] for base 
NA[1] = resultLine; //[1] for result 
blocksComparisonSet1.Add(NA); 

//if only one value found 
String[] NA = new String[2]; //keep results 
NA[0] = ""; //[0] for base 
NA[1] = resultLine; //[1] for result 
blocksComparisonSet1.Add(NA); 

//This is where I merge lists and try to remove duplicates 
if (blocksComparisonSet1.Count() > 0 || blocksComparisonSet2.Count() > 0) 
//check if we have any values in out differences lists. if we do, merge them 
{ 
    blocksComparisonFinal.AddRange(blocksComparisonSet1); 
    //add records from one list to final list 
    blocksComparisonFinal.AddRange(blocksComparisonSet2); 
    //add records from second list to final list 
    blocksComparisonFinal = blocksComparisonFinal.Distinct().ToList(); 
    //remove dublicates 
} 

-

List1[] Example  
string1 na 
string2 na 
string3 String1 
string4 String7 
string5 string8 
na string9 
na string2 

-

List2[] Example  
na string2 
na string5 
String1 string3 
String7 string4 
string8 string5 
string9 na 
string2 na 

-

Final List[] must be: 
na string9 
na string2 
na string5 
string1 na 
String1 string3 
string2 na 
string3 String1 
string4 String7 
string5 string8 
String7 string4 
string8 string5 
string9 na 
+3

Verwenden Sie keine 'Count' wenn Sie meinen' Any'. – jason

Antwort

2

Eine alternative Nicht-Linq-Lösung mit einer Implementierung von IEqualityComparer<string[]>

var merged = new HashSet<string[]>(blocksComparisonSet1, new SEC()); 
merged.UnionWith(blocksComparisonSet2); 

class SEC : IEqualityComparer<string[]> 
{ 
    public bool Equals(string[] p1, string[] p2){ 
     return p1.SequenceEqual(p2); 
    } 
    public int GetHashCode(string[] p){ 
     return (int)p.Sum (p1 => p1.GetHashCode()); 
    } 
} 
+0

Achtung! Es könnte null 'String'-Referenzen im Array geben. – jason

+0

Ok, ich werde deine kopieren :) – Phil

6
var merge = blocksComparisonSet1.Union(
       blocksComparisonSet2, 
       new ArrayEqualityComparer<string>() 
      ).ToList(); 

Sie eine benutzerdefinierte benötigen IEqualityComparer<string[]>. Siehe MSDN.

Hier ist eine Implementierung:

class ArrayEqualityComparer<T> : IEqualityComparer<T[]> { 
    public bool Equals(T[] x, T[] y) { 
     if(Object.ReferenceEquals(x, y)) { 
      return true; 
     } 
     if(x == null || y == null) { 
      return false; 
     } 
     return x.SequenceEqual(y); 
    } 

    public int GetHashCode(T[] x) { 
     if(x == null) { 
      return 0; 
     } 
     return x.Aggregate(
      0, 
      (h, item) => h^(item != null ? item.GetHashCode() : 0) 
     ); 
    } 
} 
+0

Ja, Sie brauchen definitiv eine Implementierung von IEqualityComparer . Dein Code funktioniert nicht wie er ist. – Phil

Verwandte Themen