GroupBy on complex object(例如List <T>)

Jak*_*net 13 c# linq comparison grouping

使用GroupBy()Count() > 1我试图在列表中查找我的类的重复实例.

这个类看起来像这样:

public class SampleObject
{
    public string Id;
    public IEnumerable<string> Events;
}
Run Code Online (Sandbox Code Playgroud)

这就是我实例化和分组列表的方式:

public class Program
{
    private static void Main(string[] args)
    {
        var items = new List<SampleObject>()
        {
            new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent" } },
            new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent" } }
        };

        var duplicates = items.GroupBy(x => new { Token = x.Id, x.Events })
                         .Where(g => g.Count() > 1)
                         .Select(g => g.Key)
                         .ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

duplicates不包含的项目.如何进行分组工作?

Eni*_*ity 14

要使对象与许多LINQ的运算符(例如GroupBy或)一起使用Distinct,您必须实现GetHashCode&Equals,或者必须提供自定义比较器.

在您的情况下,将属性作为列表,您可能需要一个比较器,除非您将列表设为只读.

试试这个比较器:

public class SampleObjectComparer : IEqualityComparer<SampleObject>
{
    public bool Equals(SampleObject x, SampleObject y)
    {
        return x.Id == y.Id && x.Events.SequenceEqual(y.Events);
    }

    public int GetHashCode(SampleObject x)
    {
        return x.Id.GetHashCode() ^ x.Events.Aggregate(0, (a, y) => a ^ y.GetHashCode());
    }
}
Run Code Online (Sandbox Code Playgroud)

现在这段代码有效:

    var items = new List<SampleObject>()
    {
        new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent"} },
        new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent" } }
    };

    var comparer = new SampleObjectComparer();

    var duplicates = items.GroupBy(x => x, comparer)
                     .Where(g => g.Count() > 1)
                     .Select(g => g.Key)
                     .ToList();
Run Code Online (Sandbox Code Playgroud)