2012-10-01 42 views
5

Próbuję usunąć duplikaty elementu z dolnej części ogólnej listy. Mam klasy zdefiniowane jak poniżejUsuwanie duplikatów z dołu listy ogólnej

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

I zdefiniowano innej klasy, która implementuje IEqualityComparer usunąć duplikaty z listy

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(); 
    } 
} 

Jednak staram się usunąć stare przedmioty i zachować ostatni. Na przykład, jeśli mam listę identyfikator zdefiniowany jako poniżej

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); 

I wdrożyliśmy

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

Jak mogę upewnić się, stosując odrębne że jestem utrzymując idn6 i usuwanie idn1 i idn4?

Odpowiedz

9

Most LINQ operators are order-preserving: API funkcji Distinct() mówi, że zajmie pierwszą instancję każdego znalezionego elementu. Jeśli chcesz ostatnią instancję, po prostu zrobić:

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

Innym rozwiązaniem, które pozwoliłoby uniknąć konieczności zdefiniowania wyraźnej porównywarka byłoby:

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

Od MSDN:

IGrouping Obiekty są generowane w kolejności na podstawie kolejność elementów w źródle, które wyprodukowały pierwszy klucz każdej IGrouping. Elementy w grupie są tworzone w w kolejności, w jakiej pojawiają się w źródle.

+0

Dzięki, to działa dobrze –

0

Mógłbyś Group i sprawdzić, czy jest jakikolwiek Count> 1

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

Można również realizować niestandardowe dodać metodę utrzymania najnowsze rekordy:

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);