HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Counting the occurrence of each letter in a string

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thecountingeachoccurrenceletterstring

Problem

This function counts the number of times each letter appears in a string, then display the one that appears the most, and the number of times it appears. If there's a tie, it shows all of them, like "bz,5".

I've got the feeling this could be done much better. Suggestions?

private static void LinqTest()
{
    const string testString = "abbsabwertbfacsfgggdfgascd";
    var count = 0;

    var charGroups = (from c in testString
                      group c by c into g
                      select new
                      {
                          c = g.Key,
                          count = g.Count(),
                      }).OrderByDescending(c => c.count);
    foreach (var @group in charGroups.Where(@group => count <= @group.count))
    {
        Console.WriteLine(@group.c + ": " + @group.count);
        count = @group.count;
    }
}

Solution

The trick is to group by the character, as you are doing, then do a second grouping by the count:

var testString = "abbsabwertbfacsfgggdfgasc";

var characterCounts =
    from character in testString
    group character by character into characterGroup
    group characterGroup.Key by characterGroup.Count() into countedCharacterGroup
    orderby countedCharacterGroup.Key descending
    select new
    {
        Characters = new string(countedCharacterGroup.ToArray()),
        Count = countedCharacterGroup.Key
    };

var topCharacterCount = characterCounts.First();

Console.WriteLine("{0},{1}", topCharacterCount.Characters, topCharacterCount.Count);


Breakdown

First, we do the same initial grouping:

from character in testString
group character by character into characterGroup


Next, we group the characters by the number of times they appear:

group characterGroup.Key by characterGroup.Count() into countedCharacterGroup


Then, we order based on the character counts:

orderby countedCharacterGroup.Key descending


Finally, we create a string for each set of characters with the same count:

select new
{
    Characters = new string(countedCharacterGroup.ToArray()),
    Count = countedCharacterGroup.Key
}


We can also get rid of the loop, instead grabbing the top count and writing the joined character string:

var topCharacterCount = characterCounts.First();

Console.WriteLine("{0},{1}", topCharacterCount.Characters, topCharacterCount.Count);

Code Snippets

var testString = "abbsabwertbfacsfgggdfgasc";

var characterCounts =
    from character in testString
    group character by character into characterGroup
    group characterGroup.Key by characterGroup.Count() into countedCharacterGroup
    orderby countedCharacterGroup.Key descending
    select new
    {
        Characters = new string(countedCharacterGroup.ToArray()),
        Count = countedCharacterGroup.Key
    };

var topCharacterCount = characterCounts.First();

Console.WriteLine("{0},{1}", topCharacterCount.Characters, topCharacterCount.Count);
from character in testString
group character by character into characterGroup
group characterGroup.Key by characterGroup.Count() into countedCharacterGroup
orderby countedCharacterGroup.Key descending
select new
{
    Characters = new string(countedCharacterGroup.ToArray()),
    Count = countedCharacterGroup.Key
}

Context

StackExchange Code Review Q#26775, answer score: 4

Revisions (0)

No revisions yet.