web-dev-qa-db-fra.com

Comment compter le nombre d'éléments correspondant à une condition avec LINQ

J'ai essayé beaucoup de choses mais la plus logique pour moi semble être celle-ci:

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

AllMyControls est une collection de UserControls. Ce que je veux savoir, c'est combien de UserControls ont la propriété IsActiveUserControlChecked définie sur true.

Ce que j'obtiens dans VS c'est:

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

Quel est le problème avec mon expression?

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

ou simplement

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

Puisque vous êtes débutant, il serait intéressant de jeter un coup d'œil à Enumerable documentation

43
Adrian Carneiro

Pourquoi ne pas utiliser directement Count? Cette déclaration == true est également hautement redondante.

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

De plus, vous obtenez une erreur sur votre méthode Take car elle attend un int. Vous devez spécifier le nombre d'éléments contigus à partir du début de la collection que vous souhaitez obtenir. Vous ne pouvez pas utiliser d'expression lambda. Vous devez utiliser TakeWhile pour cela. Alors 

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

aurait été correct, mais ne fonctionnerait pas comme vous le souhaiteriez; il s'arrête une fois que la condition est cassée. Ainsi, si AllMyControls contient true, true, false, true, TakeWhile avec Count renverra 2 au lieu de 3.

5

Le paramètre pour Take requiert une int et vous transmettez une expression delegate/lambda. Take est conçu pour prendre simplement la première count des éléments.

Vous pouvez utiliser la méthode Count et transmettre un délégué pour compter les éléments correspondant à ses critères. De cette façon, vous n'itérez IEnumerable qu'une seule fois, plutôt que de sélectionner d'abord ceux qui ne correspondent pas à vos critères, puis de les compter.

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

Ne pas EMBRASSER

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

Essayer

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