I have a list of data like this:
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
What I want to perform is to get reduced list like this:
Prod1: Id=4, Name="Laptop", Active=true
What I am trying to do is that I need to select all products group by its Name, and return all that has true. Since Book has one false, it should not return Book.
I've tried this one:
lstProducts = lstProducts
.Where(x =>
lstProducts
.All(c => c.Name == x.Name && c.Active == true))
.GroupBy(c => c.Name).Select(c => c.First())
.ToList();
But its returning zero results. If I do a where clause where Active == true
, its getting a Book product, which shouldn't since all of its Active should be true in order to get it.
What you are looking for is to first group all items by their Name
, then filter only those that have all true
for Active
and last retrieve the first item for each group:
var result = lstProducts.GroupBy(item => item.Name)
.Where(group => group.All(item => item.Active)
.Select(group => group.First());
If you want to ensure some ordering for the group, as in your example then:
var result = lstProducts.GroupBy(item => item.Name)
.Where(group => group.All(item => item.Active)
.Select(group => group.OrderBy(item => item.Id).First());
Group first, then filter:
lstProducts
.GroupBy(c => c.Name)
.Where(g => g.All(c => c.Active))
.Select(g => g.First())
.ToList()
GroupBy
guarantees that items within groups have the same order with respect to each other as they did before the grouping. If you’d like to choose the element with the minimum id to represent the group and your original list isn’t ordered by id, however, you can use Min
instead of First
:
lstProducts
.GroupBy(c => c.Name)
.Where(g => g.All(c => c.Active))
.Select(g => g.Min(c => c.Id))
.ToList()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With