Using Linq's GroupBy()
method, returns IEnumerable<IGrouping<TKey, TElement>>
type.
At this time, I wnat to return an anonymous type that matches TElement
to TKey
using Select()
in method call syntax.
Here's the data we use in this question.
public class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
List<Pet> pets = new List<Pet>
{
new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 },
new Pet { Name="Daisy", Age=4 }
};
I can acheive what I want by nesting foreach
in the following methodCallSyntax
.
var methodCallSyntax = pets.GroupBy(pet => pet.Age, pet => pet.Name);
foreach (var grouping in methodCallSyntax)
{
foreach (var element in grouping)
{
Console.WriteLine($"Key: {grouping.Key}, Element: {element}");
}
}
But I want to use foreach
only once.
var methodCallSyntax =
pets
.GroupBy(pet => pet.Age, pet => pet.Name)
// .Select(grouping => new {grouping.Key, Element = grouping.});
foreach (var item in methodCallSyntax)
{
Console.WriteLine($"Key: {item.Key}, Element: {item.Element}");
}
But as you can see I don't know what to fill out Select()
.
How can I do this?
CodePudding user response:
You can use SelectMany after GroupBy, and use a Select inside of SelectMany.
SelectMany transforms a multi-dimensional collection into a single sequence. The inner Select will return a collection, and SelectMany will transform all those values from Select into a single collection.
var all = pets
.GroupBy(pet => pet.Age, pet => pet.Name)
.SelectMany(group => group
.Select(name => new { key = group.Key, value = name })
);
Usage
foreach (var item in all)
{
Console.WriteLine($"Key: {item.key}, Element: {item.value}");
}