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

时间:2017-08-16 06:32:10

标签: c# linq

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

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

我想要做的是我需要按名称选择所有产品组,并返回所有真实的产品。由于Book有一个假,它不应该返回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,它就会获得一个Book产品,因为它的所有Active都应该是真的才能得到它。

2 个答案:

答案 0 :(得分:8)

您要找的是首先按照Name对所有项目进行分组,然后仅过滤那些true Active的所有项目,并最后检索每个组的第一项:

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());

答案 1 :(得分: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()