Look at it from the inner test first:
A
Principle
should be included in the output if the
Emailaddress
matches
any of the
Email
values in groupUsers:
groupUsers.Any(gu => gu.Email == u.Emailaddress)
Now do that for each element of users and collect the result:
IEnumerable<Principle> result = users.Where(u => groupUsers.Any(gu => gu.Email == u.Emailaddress));
This, of course, is very inefficient. Time grows proportional to the
product of the lengths of the two lists. So make the inner test faster:
HashSet<string> groupEmails = new HashSet<string>(groupUsers.Select(gu => gu.Email));
IEnumerable<Principle> result = users.Where(u => groupEmails.Contains(u.Emailaddress));
This now takes time proportional to the
sum of the lengths of the two lists.
Creating and populating the
groupEmails
is a single pass over the
groupUsers
collection.
Finding the result is a single pass over the
users
collection.
The advantage is that the
groupEmails.Contains(...)
is (approximately) constant time, independent of the number of elements in the
groupEmails HashSet
.
* Gramatically, you probably mean "Principal" not "Principle"... lookup the difference:
Principal vs Principle[
^]