LINQ and lambdas - Get Control of your data - queries, OrderBy, GroupBy, Select, Join methods, switch expression
Head First C#: A Learner’s Guide to Real-World Programming with C# and .NET Core (Andrew Stellman(著)、Jennifer Greene(著)、O’Reilly Media)のChapter 9(LINQ and lambdas - Get Control of your data)、p.519(Exercise)の解答を求めてみる。
コード
ComicAnalyzer.cs
using System;
using System.Collections.Generic;
using System.Linq;
namespace JimmyLinq
{
static class ComicAnalyzer
{
// せっかくだからこれも三項演算子を利用したLambda式に修正
private static PriceRange CalculatePriceRange(Comic comic) =>
Comic.Prices[comic.Issue] < 100 ? PriceRange.Cheap : PriceRange.Expensive;
internal static IEnumerable<IGrouping<PriceRange, Comic>>
GroupComicsByPrice(IEnumerable<Comic> catalog,
IReadOnlyDictionary<int, decimal> prices) =>
catalog
.OrderBy(comic => prices[comic.Issue])
.GroupBy(comic => CalculatePriceRange(comic));
internal static IEnumerable<string>
GetReviews(IEnumerable<Comic> catalog, IEnumerable<Review> reviews) =>
catalog
.OrderBy(comic => comic.Issue)
.Join(reviews,
comic => comic.Issue,
review => review.Issue,
(comic, review) => $"{review.Critic} rated #{review.Issue} '{comic.Name}' {review.Score}");
}
}
コード
Program.cs
using System;
namespace JimmyLinq
{
class MainClass
{
public static void Main(string[] args)
{
var done = false;
while (!done)
{
Console.WriteLine(
"\nPress G to group comics by price, R to get reviews, any other key to quit\n");
done = Console.ReadKey(true).KeyChar.ToString().ToUpper() switch
{
"G" => GroupComicsByPrice(),
"R" => GetReviews(),
_ => true,
};
}
}
private static bool GroupComicsByPrice()
{
var groups = ComicAnalyzer.GroupComicsByPrice(Comic.Catalog, Comic.Prices);
foreach (var group in groups)
{
Console.WriteLine($"{group.Key} comics:");
foreach (var comic in group)
{
Console.WriteLine(
$"#{comic.Issue} {comic.Name}: {Comic.Prices[comic.Issue]:c}");
}
}
return false;
}
private static bool GetReviews()
{
var reviews = ComicAnalyzer.GetReviews(Comic.Catalog, Comic.Reviews);
foreach (var review in reviews)
{
Console.WriteLine(review);
}
return false;
}
}
}
入出力結果(Terminal, Zsh)
Press G to group comics by price, R to get reviews, any other key to quit
Cheap comics:
#83 Tribal Tatto Madness: $25.75
#97 The Death of the Object: $35.25
#74 Black Monday: $75.00
Expensive comics:
#68 Revenge of the New Wave Freak (damaged): $250.00
#19 Rock and Roll (limited edition): $500.00
#36 Woman's Work: $650.00
#6 Johnny America vs. the Pinko: $3,600.00
#57 Hippie Madness (misprinted): $13,525.00
Press G to group comics by price, R to get reviews, any other key to quit
MuddyCritic rated #36 'Woman's Work' 37.6
RottenTornadoes rated #74 'Black Monday' 22.8
MuddyCritic rated #74 'Black Monday' 84.2
RottenTornadoes rated #83 'Tribal Tatto Madness' 89.4
MuddyCritic rated #97 'The Death of the Object' 98.1
Press G to group comics by price, R to get reviews, any other key to quit