Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With LINQ, get count of items that satisfy criteria in grouping

Tags:

c#

.net

linq

I'm probably going to butcher the terminology if I try too hard, so it'll be easier to describe via code:

var fooGroup = fooList.GroupBy(x => x.SomeID);
//fooGroup is now of type IEnumerable<IGrouping<int, Foo>>
var someCount = fooGroup.Count(y => y.Where(f => f.Bar == "Bar"));

The above will not compile due to this error: "Cannot convert lambda expression to delegate type System.Func<System.Linq.IGrouping<int,Foo>,bool> because some of the return types in the block are not implicitly convertible to the delegate return type"

I assume the answer is pretty easy, but I can't quite wrap my head around how to do this.

like image 308
Matt Avatar asked Feb 13 '13 23:02

Matt


3 Answers

Try this:

var someCount = fooGroup.Sum(y => y.Where(f => f.Bar == "Bar").Count());

Or even more clean

var someCount = fooGroup.Sum(y => y.Count(f => f.Bar == "Bar"));
like image 160
Jens Kloster Avatar answered Oct 28 '22 14:10

Jens Kloster


What you're trying to do with a group by does not make a whole lot of sense. I propose the following.

If you're looking for how many elements have Bar == "Bar", then do it before the group.

var someCount = fooList.Count(y => f.Bar == "Bar");

If you're looking to count the groups which contain an element which matches the same criteria.

var fooGroup = fooList.GroupBy(x => x.SomeID)
    .Where(x => x.Any(z => z.Bar == "Bar")).Count();
like image 44
Khan Avatar answered Oct 28 '22 15:10

Khan


The IEnumerable<IGrouping<int, Foo>> you get by grouping.

It is an IEnumerable of groups. The group has a key type of int, which is because you grouped by the int id column. The grouping contains an IEnumerable which contains the list of objects which all have this key. It is of type Foo.

Then it is a simple query. From the grouping you find those that have the wanted key (i.e. the int id), and then select the count from the groups IEnumerable.

var fooGrouping = fooList.GroupBy(x => x.SomeID);
var someCount = fooGrouping.Where(grp => grp.Key == someKey).Select(p=>p.Count());
like image 40
h.alex Avatar answered Oct 28 '22 16:10

h.alex