LINQ fun - part two

Just a quick post, for part two let's look at grouping our results for display purposes... first off, I grab only the episodes which we think are "valid" (in this case ones which are assigned a series, episode and part number)...

EpisodeParser episodeParser = new EpisodeParser();

YouTubeSearcher searcher = new YouTubeSearcher(DeveloperId);

// get a list of all the parts we are interested in

IEnumerable parts = (from result in searcher.QueryByTags("QI", "Quite", "Interesting")
select episodeParser.Parse(result))
.Where(p => p.SeriesNumber > 0 && p.EpisodeNumber > 0 && p.PartNumber > 0)
.Distinct();

Obviously what I've done here is probably rather poor style, surely the where clause could have been inside the select statement??... but I'm just trying to illustrate how you can mix the two notations... next we're going to group the results up using some nested "group by" and object projections... this is disgustingly easy, what more can you say about it.

// group those parts

var allSeries = from part in parts
group part by part.SeriesNumber into series
orderby series.Key
select new { SeriesNumber = series.Key,
Episodes = from episodePart in series
group episodePart by episodePart.EpisodeNumber into episodes
orderby episodes.Key
select new {EpisodeNumber = episodes.Key,
Parts = from chunk in episodes
orderby chunk.PartNumber
select chunk
}
};

Great, I think that saved us a lot of time, compared to doing it ourselves in C# 2.0...  let's now generate a little page to view the results - for now I'm just writing code in NUnit fixtures - so we'll use Console.WriteLine... though in a website I would probably just use some quite similar brail template code.

foreach (var series in allSeries)
{
Console.WriteLine("

Series {0}

rn", series.SeriesNumber);
foreach (var episode in series.Episodes)
{
Console.WriteLine("

Episode {0}

rn", episode.EpisodeNumber);

foreach (var author in episode.Parts.GroupBy(p => p.Result.Author))
{
Console.WriteLine("

Author: {0}rn", author.Key);

foreach(var part in author)
{
YouTubeResult result = part.Result;
Console.WriteLine("part {1}  ", result.Url, part.PartNumber, result.ThumbUrl);
}
}
}
}

I've also dumped the output from this to an html page, if you'd like to have a look at it.

Next time I might have a look at storing the results of the youtube query with base4 and writing some code for a little daemon which can identify newly posted episode parts on a periodic basis... which should all lead towards implementing the RSS feed capability I discussed in  part one.

But for now I'm off to enjoy the sun!

Written on February 5, 2007