如何使用LINQ查找特定属性的重复项?

37
Customer customerOne = new Customer("John", "Doe");
Customer customerTwo = new Customer("Super", "Man");
Customer customerThree = new Customer("Crazy", "Guy");
Customer customerFour = new Customer("Jane", "Doe");
Customer customerFive = new Customer("Bat", "Man");

List<Customer> customers = new List<Customer>();
customers.Add(customerOne);
customers.Add(customerTwo);
customers.Add(customerThree);
customers.Add(customerFour);
customers.Add(customerFive);

使用什么LINQ查询可以返回一个枚举,包含所有姓氏相同的客户?

结果应该包括以下实例:John Doe、Jane Doe、Super Man和Bat Man。

4个回答

61
重新表述:“你想按姓氏对客户列表进行分组,过滤掉有多个元素的组,并选择每个组的每个实例”。你几乎可以直接将这句话翻译成C#代码。
 customers
    .GroupBy(customer => customer.LastName)
    .Where(sameLastName => sameLastName.Skip(1).Any())
    .SelectMany(customer => customer)

或者使用LINQ语法:
var q = from customer in customers
        group customer by customer.LastName into sameLastName
        where sameLastName.Skip(1).Any()
        from customer in sameLastName
        select customer;

找了很久才找到。谢谢! - Wrightboy
2
这应该是正确的答案。对我有效,其他的不行。 - dave317

17
    var result = from c in customers
                 join c2 in customers on c.LastName equals c2.LastName
                 where c != c2
                 select c;

3
这种语法上稍微更加优雅一些,比“按组排序”的解决方案更加简洁,但性能也更差(不过显然只有在非常大的列表中才会有明显的差别)。 - jeroenh
同意。这是O(n sqrt(n))和O(n^2)的比较吗? - Mikael Eliasson
看看使用SQL查询时是否更高效会很有趣;自连接可能更自然地处理查询优化器,但我不确定提供程序对于Group By解决方案会产生什么样的SQL。 - Dan Bryant
@Dan Bryant 可能是这样,但这完全取决于 Linq 提供程序,还有实际的数据库引擎。问题没有提到任何数据库技术,所以我假设它是关于 Linq 2 对象的... - jeroenh

8
var groups = customers.GroupBy(c => c.LastName).Where(g => g.Skip(1).Any());
foreach(var group in groups) {
    Console.WriteLine(group.Key);
    foreach(var customer in group) {
        Console.WriteLine("\t" + customer.FirstName);
    }
}

输出:

Doe
        John
        Jane
Man
        Super
        Bat

您可以使用以下方法将结果序列中的所有组展平为一个序列:
var list = groups.SelectMany(g => g);

-1
如果您只想查找是否存在重复项,可以使用此技巧。
var result = customers.GroupBy(c => c.Id).Count() != customers.Count();

1
如果你只是想查找是否有重复项。是的,但它们不存在。 - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接