【问题标题】:C# sort string alphabetically followed by frequency of occurrenceC#按字母顺序排序字符串,后跟出现频率
【发布时间】:2018-11-20 14:56:08
【问题描述】:

我刚开始学习 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()}");
}

这是输出:

t1 r2 e1 i1 l2

需要输出:

e1i1l2r2t1

不知道如何正确排序。对我做错了什么有任何想法吗?

【问题讨论】:

  • frequency = frequency.OrderBy(x => x.Count);
  • 您只是想通过letterfrequency.Key 订购,然后通过letterfrequency.Count() 订购?鉴于您的分组,后者无关紧要。
  • 你能解释一下为什么你在那里写了一个不必要的ToList吗?我有兴趣了解人们为什么要编写不必要的代码,因为它可以帮助我设计 API,让开发人员避免编写不必要的代码。
  • “跟随”是指打印出密钥,然后按计数跟随?还是您的意思是排序关系取决于计数?如果是后者,那有什么不同?
  • ToList() 是我最初尝试排序的方法之一,因为我无法让它正常工作。我知道,编码不好,但我正在尝试:) 非常感谢

标签: c# linq


【解决方案1】:

您缺少的是在您的 LINQ 语句中添加 orderby

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}");
}

letterfrequency 有一个名为 Key 的属性,其中包含每个组的字母,因此添加 orderby letterfrequency.Key 会对结果进行排序,从而为您提供所需的输出:

e1

i1

l2

r2

t1

我还稍微调整了查询​​的结果(只是为了表明这是可能的)以生成一个新的匿名类型,其中包含作为命名属性的字母和频率。这使得Console.WriteLine 中的代码更加清晰,因为使用的属性称为LetterFrequency,而不是KeyCount() 方法。

使用 C# 7.0 元组将其变为 11

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

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}");
}

我有 blogged about this,有很多 other resourcesdescribe them,包括这个 Stackoverflow 问题,询问“Are C# anonymous types redundant in C# 7”,如果您想更深入地了解元组,它们是什么,它们是如何工作以及为什么/何时您可能希望优先使用它们而不是匿名类型。

【讨论】:

  • .ToList() 是多余的
  • 虽然这很好,但可以从两个小方面进行改进。 (1) 删除不必要的 ToList,以及 (2) 在 C# 7 中,选择成元组而不是匿名类型。
【解决方案2】:

只需将您的列表排序如下:

        foreach (var f in frequency.OrderBy(item=>item.Key))
        {
            Console.WriteLine($"{f.Key}{f.Count()}");
        }

【讨论】:

    【解决方案3】:

    我会选择一个匿名对象:

    var frequency = from f in "trreill"
                         group f by f into letterfrequency
                         select new { Key = letterfrequency.Key, Count = letterfrequency.Count() };
    

    那么我会这样订购:

    foreach (var f in frequency.OrderBy(x => x.Key))
    {
        Console.WriteLine($"{f.Key}{f.Count}");
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-06
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 2019-09-17
      • 2020-04-16
      • 2015-07-22
      • 2021-02-21
      • 1970-01-01
      相关资源
      最近更新 更多