C#按字母顺序排序字符串,后跟出现频率

MBr*_*ers 2 c# linq

我刚开始学习lambda/linq.这是我到目前为止所拥有的.

var frequency = from f in "trreill".ToList()
                group f by f into letterfrequency
                select letterfrequency;

foreach (var f in frequency)
{
    Console.WriteLine($"{f.Key}{f.Count()}");
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

t1 r2 e1 i1 l2

需要的输出:

e1i1l2r2t1

无法弄清楚如何正确排序.对我做错了什么的想法?

Rob*_*Rob 6

你缺少的是添加一个orderbyLINQ语句:

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}");
}
Run Code Online (Sandbox Code Playgroud)

letterfrequency有一个名为属性Key包含每个组的字母,因此添加orderby letterfrequency.Key各种效果给你你后的输出:

E1

I1

L2

R2

T1

我还稍微调整了查询​​的结果(只是为了表明它是可能的)来生成一个新的匿名类型,其中包含Letter和Frequency作为命名属性.这使得在所述代码Console.WriteLine一个littl更清晰的作为正在使用的属性被称为LetterFrequency,而不是KeyCount()方法.

使用C#7.0元组将其调高到11

如果您使用的是C#7.0,则可以使用Tuples替换匿名类型的使用,这意味着代码现在看起来像这样:

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}");
}
Run Code Online (Sandbox Code Playgroud)

我已经在博客上发表了这篇文章,还有很多其他资源可以描述它们,包括这个Stackoverflow问题,如果你想更深入地了解元组,它们是什么,它们是怎样的,它们会问" C#7中C#匿名类型是多余的 "工作以及为什么/何时可能希望使用它们优先于匿名类型.

  • 虽然这很好,但可以通过两种小方式进行改进.(1)删除不必要的ToList,并且(2)在C#7中,选择一个元组而不是一个匿名类型. (2认同)