I am not sure if this question is a duplicate or not as this is something that I struggled a lot to search for as basically I don't know what would be the functionality name. So if that's the case my apologies.
Take an example where a team has persons and the person has several phone numbers, I would like to group by Number and still maintain all the information related with the team. So basically make the property Number the key of my groupby.
public class PhoneNumber
{
public string Number { get; set; }
}
public class Person
{
public List<PhoneNumber> PhoneNumbers { get; set; }
}
public class Team
{
public List<Person> Persons{ get; set; }
}
IEnumerable<Team> teams = new List<Team>();
So I would like to do something similar to:
Team.Persons.GroupBy(i=> i.PhoneNumbers.Number)
which obviously I can't because PhoneNumbers is a List
The end result should be something like
Where NumberX is the groupby key and TeamX contains the information associated with a team that has a member with that phone number.
It might be that my approach is entirely out of place on this example so any feedback would be appreciated.
You basically need to flatten the results so you've got team/number pairs and then you can group by the number. So for example:
// IEnumerable<IGrouping<string, Team>>
var grouped = from team in teams
from person in team.Persons
from number in person.PhoneNumbers
group team by number.Number;
You might also want to consider creating a Lookup
instead of grouping:
// ILookup<string, Team>
var lookup = (from team in teams
from person in team.Persons
from number in person.PhoneNumbers
select new { team, number }).ToLookup(p => p.number.Number,
p => p.team);
With the lookup, you can just do things like:
var number = "...";
foreach (var team in lookup[number])
{
...
}
... and it will helpfully return an empty sequence if you ask for the teams with an unknown phone number.
See more on this question at Stackoverflow