The thing you're missing is adding an orderby
to your LINQ statement:
var frequency = from f in "trreill"
group f by f into letterfrequency
orderby letterfrequency.Key
select new
{
Letter = letterfrequency.Key,
Frequency = letterfrequency.Count()
};
foreach (var f in frequency)
{
Console.WriteLine($"{f.Letter}{f.Frequency}");
}
The letterfrequency
has a property called Key
which contains the letter for each group, so adding orderby letterfrequency.Key
sorts the results to give you the output you're after:
e1
i1
l2
r2
t1
I've also tweaked the result of the query slightly (simply to show that it's something that's possible) to generate a new anonymous type that contains the Letter and the Frequency as named properties. This makes the code in the Console.WriteLine
a littl clearer as the properties being used are called Letter
and Frequency
rather than Key
and the Count()
method.
Turning it up to 11, using C# 7.0 Tuples
If you're using C# 7.0, you could replace the use of an anonymous type with Tuples, that means that the code would now look like this:
var frequency = from f in "trreill"
group f by f into letterfrequency
orderby letterfrequency.Key
select
(
Letter: letterfrequency.Key,
Frequency: letterfrequency.Count()
);
foreach (var (Letter, Frequency) in frequency)
{
Console.WriteLine($"{Letter}{Frequency}");
}
I've blogged about this, and there are plenty of other resources that describe them, including this Stackoverflow question that asks 'Are C# anonymous types redundant in C# 7', if you want a deeper dive into Tuples, what they are, how they work and why/when you might want to use them in preference to anonymous types.