使用LINQ获取所有属性具有完全相同值的对象?

6

我有一个类似这样的数据列表:

Prod1: Id=1,  Name="Book",    Active=true
Prod2: Id=2,  Name="Book",    Active=false
Prod3: Id=3,  Name="Book",    Active=true
Prod4: Id=4,  Name="Laptop",  Active=true
Prod5: Id=5,  Name="Laptop",  Active=true
Prod6: Id=6,  Name="Laptop",  Active=true

我想要实现的是获取类似于以下缩减列表的功能:
Prod1: Id=4, Name="Laptop", Active=true

我需要做的是按名称选择所有产品,并返回所有true的产品。由于Book有一个false,所以不应返回Book。

我尝试了这个:

lstProducts = lstProducts 
                .Where(x =>
                    lstProducts 
                   .All(c => c.Name == x.Name && c.Active == true))
                .GroupBy(c => c.Name).Select(c => c.First())
                .ToList();

但是它返回了零个结果。如果我使用where clause where Active == true,它会得到一个书籍产品,这不应该发生,因为所有的Active都应该是true才能得到它。
2个回答

9
你需要做的是首先按照它们的“名称”对所有项目进行分组,然后仅筛选那些所有“Active”都为“true”的项目,最后检索每个组的第一个项目。
var result = lstProducts.GroupBy(item => item.Name)
                        .Where(group => group.All(item => item.Active)
                        .Select(group => group.First());

如果您想为该组保证一些排序,就像您的示例一样,那么:
var result = lstProducts.GroupBy(item => item.Name)
                        .Where(group => group.All(item => item.Active)
                        .Select(group => group.OrderBy(item => item.Id).First());

4

先进行分组,然后再进行筛选:

lstProducts
    .GroupBy(c => c.Name)
    .Where(g => g.All(c => c.Active))
    .Select(g => g.First())
    .ToList()

GroupBy保证组内的项目相对于彼此具有与分组之前相同的顺序。然而,如果您希望选择最小ID元素来代表组,并且原始列表不按ID排序,则可以使用Min而不是First

lstProducts
    .GroupBy(c => c.Name)
    .Where(g => g.All(c => c.Active))
    .Select(g => g.Min(c => c.Id))
    .ToList()

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