Sturm
Sturm

Reputation: 4125

How to count the number of elements that match a condition with LINQ

I've tried a lot of things but the most logical one for me seems this one:

int divisor = AllMyControls.Take(p => p.IsActiveUserControlChecked).Count();

AllMyControls is a Collection of UserControls, what I want to know is how many UserControls have the IsActiveUserControlChecked property set to true.

What I get in VS is:

Cannot convert lambda expression to type 'int' because it is not a delegate type

What's wrong with my expression?

Upvotes: 37

Views: 97545

Answers (5)

Felipe Oriani
Felipe Oriani

Reputation: 38638

Do not KISS

int divisor = AllMyControls.Count(p => p.IsActiveUserControlChecked);

Upvotes: 2

Adriano Carneiro
Adriano Carneiro

Reputation: 58645

int divisor = AllMyControls.Where(p => p.IsActiveUserControlChecked).Count()

or simply

int divisor = AllMyControls.Count(p => p.IsActiveUserControlChecked);

Since you are a beginner, it would be worthwhile to take a look at Enumerable documentation

Upvotes: 85

Cemafor
Cemafor

Reputation: 1653

The parameter for Take requres an int and you are passing in a delegate/ lambda expression. Take is designed to just take the first count of the elements.

You can use the Count method and pass in a delegate to count the elements that fit its criteria. This way you only iterate the IEnumerable once, rather than first culling out the ones that don't fit your criteria, and then again to actually count them.

AllMyControls.Count(p => p.IsActiveUserControlChecked);

Upvotes: 1

Pierre-Luc Pineault
Pierre-Luc Pineault

Reputation: 9201

Why not directly use Count? That == true statement is also highly redundant.

int divisor = AllMyControls.Count(p => p.IsActiveUserControlChecked);

Also, you are getting an error on your Take method because it is waiting for an int. You need to specify the number of contiguous elements from the start of the collection you want to get, you cannot put a lambda expression. You need to use TakeWhile for that. So

int divisor = AllMyControls.TakeWhile(p => p.IsActiveUserControlChecked == true).Count();

would have been correct, but would not work the way you expect it; it stops once the condition is broken. So if AllMyControls contains true, true, false, true, TakeWhile with Count will return 2 instead of your expected 3.

Upvotes: 9

bobek
bobek

Reputation: 8020

Try

int divisor = AllMyControls.Where(x => x.IsActiveUserControlChecked == true).Count();

Upvotes: 0

Related Questions