使用 Linq 计算字符串中的字符时重复输出

Duplicated output when counting chars in a string with Linq

我的这段代码的输出有这个问题,它输出字符串中一个字符被提及的次数。

class Program
{
    static void Main(string[] args)
    {
        string str = Console.ReadLine().ToLower();
        string sortedString = String.Concat(str.OrderBy(c => c));

        foreach (char ch in sortedString)
        {
            Console.WriteLine($"{ch} => {str.Count(x => x == ch)}");
        }
    }
}

这是我得到的输出:

Alabala
a => 4
a => 4
a => 4
a => 4
b => 1
l => 2
l => 2

这是我想要得到的输出

Alabala
a => 4
b => 1
l => 2

如果有人帮助我,我将不胜感激。

您可以像下面这样在单个 linq 中执行此操作:

string str =  Console.ReadLine().ToLower();
string sortedString = String.Concat(str.OrderBy(c => c));

var result = sortedString.GroupBy(x => x)
                         .Select(y => string.Format("{0} => {1}", y.Key, y.Count())).ToList();

foreach (var output in result)
{
    Console.WriteLine(output);
}

您可以结合使用 ToDictionary()OrderBy()Distinct() 方法:

        string str = "halleluyah";

        var grouppedChars = str
            .Distinct()       // removes duplicates
            .OrderBy(c => c)  // orders them alphabetically
            .ToDictionary(    // converts to dictionary [string, int]
                c => c,
                c => str.Count(c2 => c2 == c));

        foreach (var group in grouppedChars)
        {
            Console.WriteLine($"{group.Key} => {group.Value}");
        }

        Console.ReadKey();

输出:

a => 2
e => 1
h => 2
l => 3
u => 1
y => 1

P.S。 这比 GroupBy() 更好,因为您真的不想将这些字符分组在某个地方,而是只保留它们的数量。

方法二,添加自己的struct和char信息:

        struct CharStatistics
        {
           public readonly char @char;
           public readonly int count;

           public CharStatistics(char @char, int count)
           {
              this.@char = @char;
              this.count = count;
           }
        }

在主要方法中:

        string str = "halleluyah";

        var charsInfo = str
            .OrderBy(c => c)
            .Distinct()
            .Select(c =>
                new CharStatistics(c, str.Count(c2 => c2 == c)));

        foreach (var stats in charsInfo)
        {
            Console.WriteLine($"{stats.@char} => {stats.count}");
        }