我正在尝试从通用列表底部删除重复项。我的课程定义如下
public class Identifier
{
public string Name { get; set; }
}
我已经定义了另一个实现IEqualityComparer的类来从List
中删除重复项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();
}
}
但是,我正在尝试删除旧项目并保留最新项目。例如,如果我有如下定义的标识符列表
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);
我已经实施了
var res = list.Distinct(new DistinctIdentifierComparer());
我如何通过使用distinct来确保我保留idn6并删除idn1和idn4?
答案 0 :(得分:9)
Most LINQ operators are order-preserving:Distinct()的API表示它会占用每个项目的第一个实例。如果你想要最后一个实例,只需执行:
var res = list.Reverse().Distinct(new DistinctIdentifierComparer());
避免必须定义显式比较器的另一个选项是:
var res = list.GroupBy(i => i.Name).Select(g => g.Last());
来自MSDN:
IGrouping对象按照基于的顺序产生 生成第一个键的源中元素的顺序 每个IGrouping。分组中的元素产生于 它们出现在源中的顺序。
答案 1 :(得分:1)
您还可以实现自定义添加方法来维护最新记录:
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);
答案 2 :(得分:0)
您可Group
并检查是否有任何Count
&gt; 1
var distinctWorked = !(res
.GroupBy(a => a.Name)
.Select(g => new{g.Key, Count = g.Count()})
.Any(a => a.Count > 1));