Reputation: 1545
Let's say I have a Track
class that has a string[] Genres
property.
How can I efficiently group Track
elements into genres with one entry being a part of multiple groups if needed? For example, for following collection:
A - Rock
B - Pop, Rock
C - Rock, Soundtrack
D - Pop, Soundtrack
The result for this should be:
Rock - A, B, C
Pop - B, D
Soundtrack - C, D
Is there any easy way to do that using LINQ? Or is there a more efficient way than using LINQ alltogether?
Thanks!
Upvotes: 0
Views: 650
Reputation: 53958
You could try something like this:
var genresTracks = tracks.SelectMany(track => track.Genres, (track, genre) => new
{
// you might want to correct the Name property
// with the correct one.
Track = track.Name,
Genre = genre
})
.GroupBy(tg => tg.Genre)
.Select(gr => new
{
Genre = gr.Key,
Tracks = gr.Select(x=>x.Track)
});
foreach(var genreTracks in genresTracks)
{
var tracksCsv = string.Join(",", genreTracks.Tracks);
Console.WriteLine($"{genreTracks.Genre} - {tracksCsv}");
}
Initially we flatten our collection using the SelectMany
method, to a sequence of anonymous objects with two properties, Track - the track's name and Genre - one of the genres, in which this track can be categorized to. So the newly sequence would pe consisted of pairs like ("A","Rock"), ("B","Rock"), ("B","Pop"), etc. Then we GroupBy
this sequence based on the Genre property, so groups are created with key the Genre and Members the track names. Last we project each group into an object with two properties the Genre
and the Tracks
.
Upvotes: 4