2012-10-01 9 views
5

Ich versuche, Duplikate aus dem unteren Bereich der generischen Liste zu entfernen. Ich habe Klasse definiert, wie untenEntfernen von Duplikaten am Ende der Generischen Liste

public class Identifier 
{ 
    public string Name { get; set; } 
} 

Und ich habe eine andere Klasse definiert, die IEqualityComparer die Duplikate aus Liste

public class DistinctIdentifierComparer : IEqualityComparer<Identifier> 
{ 
    public bool Equals(Identifier x, Identifier y) 
    { 
     return x.Name == y.Name; 
    } 

    public int GetHashCode(Identifier obj) 
    { 
     return obj.Name.GetHashCode(); 
    } 
} 

jedoch entfernen implementiert, Ich versuche, die alten Elemente und halten Sie die neuesten zu entfernen. Zum Beispiel, wenn ich Liste der Bezeichner wie folgt definiert

Identifier idn1 = new Identifier { Name = "X" }; 
Identifier idn2 = new Identifier { Name = "Y" }; 
Identifier idn3 = new Identifier { Name = "Z" }; 
Identifier idn4 = new Identifier { Name = "X" }; 
Identifier idn5 = new Identifier { Name = "P" }; 
Identifier idn6 = new Identifier { Name = "X" }; 

List<Identifier> list = new List<Identifier>(); 
list.Add(idn1); 
list.Add(idn2); 
list.Add(idn3); 
list.Add(idn4); 
list.Add(idn5); 
list.Add(idn6); 

Und ich habe

var res = list.Distinct(new DistinctIdentifierComparer()); 

implementiert Wie stelle ich sicher, dass durch unterschiedliche Verwendung, dass ich idn6 bin zu halten und idn1 und idn4 zu entfernen?

Antwort

9

Most LINQ operators are order-preserving: Die API von Distinct() sagt, dass es die erste Instanz jedes Elements, auf das es stößt, übernimmt. Wenn Sie die letzte Instanz möchten, gehen Sie einfach:

var res = list.Reverse().Distinct(new DistinctIdentifierComparer()); 

Eine weitere Option, die verhindern würden Sie einen expliziten Vergleich definieren zu müssen wäre:

var res = list.GroupBy(i => i.Name).Select(g => g.Last()); 

Von MSDN:

Die IGrouping Objekte werden in einer Reihenfolge basierend auf die Reihenfolge der Elemente in der Quelle, die den ersten Schlüssel von jeder IGrouping produziert ergeben. Elemente in einer Gruppierung ergeben sich in der Reihenfolge, in der sie in der Quelle erscheinen.

+0

Danke, es funktioniert gut –

0

Sie könnten Group und nachzusehen, ob eine Count ist> 1

var distinctWorked = !(res 
.GroupBy(a => a.Name) 
.Select(g => new{g.Key, Count = g.Count()}) 
.Any(a => a.Count > 1)); 
1

Sie auch eine benutzerdefinierte Add-Methode implementieren könnte die neuesten Aufzeichnungen führen:

public class IdentifierList : List<Identifier> 
{ 
    public void Add(Identifier item) 
    { 
     this.RemoveAll(x => x.Name == item.Name); 
     base.Add(item); 
    } 
} 

Identifier idn1 = new Identifier { Name = "X" }; 
Identifier idn2 = new Identifier { Name = "Y" }; 
Identifier idn3 = new Identifier { Name = "Z" }; 
Identifier idn4 = new Identifier { Name = "X" }; 
Identifier idn5 = new Identifier { Name = "P" }; 
Identifier idn6 = new Identifier { Name = "X" }; 

IdentifierList list = new IdentifierList(); 
list.Add(idn1); 
list.Add(idn2); 
list.Add(idn3); 
list.Add(idn4); 
list.Add(idn5); 
list.Add(idn6); 
Verwandte Themen