5

我正在尝试从通用列表底部删除重复项。我的类定义如下

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?

4

3 回答 3

9

大多数 LINQ 操作符都是保留顺序的:Distinct() 的 API 表示它将获取遇到的每个项目的第一个实例。如果您想要最后一个实例,只需执行以下操作:

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

另一个避免您必须定义显式比较器的选项是:

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

来自 MSDN:

IGrouping 对象的生成顺序基于 source 中生成每个 IGrouping 的第一个键的元素的顺序。分组中的元素按照它们在源中出现的顺序产生。

于 2012-10-01T23:59:23.883 回答
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);
于 2012-10-02T00:07:22.160 回答
0

你可以Group检查是否Count有 > 1

var distinctWorked = !(res
.GroupBy(a => a.Name)
.Select(g => new{g.Key, Count = g.Count()})
.Any(a => a.Count > 1));
于 2012-10-02T00:01:17.333 回答