4
\$\begingroup\$

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;
    }
}
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

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);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.