Reputation: 31
I have this kind of structure :
At first, there is a list of families.
EDIT: each family contains a group of person
EDIT: each person is defined by a gender
I have to count how many of those persons are males, and how many are females, so here is what I tried:
int boys = ListOfFams.Where(f => f.persons.Where(p => p.gender == gender.male)).Count();
It seems I cannot just ask for the number of males or females because I need a condition to put after the first "where", but then, I don't know how I should build my request.
Do you guys have any idea ?
Thank you for your time
Edit again: Thank you all for your answers, and sorry for the late edit on the question regarding the group of persons etc.
Upvotes: 1
Views: 1479
Reputation: 13783
The other answers are also correct, but there is a third way.
Essentially, you're not interested in the families, but the people in those families. Rather than performing a nested count (once per family) which you then sum, you can also:
IEnumerable<Person> allPeopleInTheseFamilies = ListOfFams.SelectMany(fam => fam.persons);
int totalMales = allPeopleInTheseFamilies.Count(person => person.gender == gender.male);
This can of course be chained as well:
int totalMales = ListOfFams
.SelectMany(fam => fam.persons)
.Count(person => person.gender == gender.male);
If you're worried about nullability, you can add in extra null checks (though I would generally advise to avoid having nulls in the list in the first place)
int totalMales = ListOfFams
.Where(fam => fam != null && fam.persons != null)
.SelectMany(fam => fam.persons)
.Count(person => person != null && person.gender == gender.male);
Upvotes: 1
Reputation: 3701
if you select each family, then return the count of males in it, you would get an enumerable of counts - e.g {0,1,0,3,2,1} - you can then simply Sum those counts
ListOfFams.Select(f => f.persons.Where(p => p.gender == gender.male).Count()).Sum();
//to reject nulls
ListOfFams.
Where(f => f != null && f.persons != null).
Select(f => f.persons.
Where(p => p != null && p.gender == gender.male).
Count()).
Sum();
Upvotes: 1
Reputation: 43886
You can simply use LINQ's Count()
and Sum()
to achieve that:
int boy = ListOfFams.Sum(f => f.persons.Count(p => p.gender == gender.male));
This counts the male persons per family and sums up the results.
If you expect any of those collections to contain null
values, you need to protect against that like this:
int boy = ListOfFams.Sum(f => f?.persons?.Count(p => p?.gender == gender.male) ?? 0);
Now this only counts persons that are not null
and male, and only persons of families that are not null
and whose persons
list is not null
.
If a family or a persons
collection is null
, they are counted as 0
.
Upvotes: 3