Question

Essentially, I found an old piece of LINQ C# code that counted the most frequent letter in a certain string. However, I'm using frequency analysis to solve a decoded text that has been shift-ciphered so I'm wanting it to return not just the most popular char, but a char array ordered by frequency of appearance.

Here is the LINQ code I found on here:

input.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key
Was it helpful?

Solution

Well you pretty much have it already.

input.GroupBy(x => x).OrderByDescending(x => x.Count()).Select(x => x.Key).ToArray();

OTHER TIPS

Replacing .First().Key with .Select(group => group.Key) should return to you the characters sorted by frequency in descending order.

Here's a solution that doesn't use LINQ, which might be understandable without learning LINQ:

// count all the frequencies
var frequencies = new Dictionary<char, int>;
foreach(char c in input)
{
    if(frequencies.ContainsKey(c))
    {
        frequencies[c]++;
    }
    else
    {
        frequencies.Add(c, 1);
    }
}
// Get the characters
var characters = new List<char>(frequencies.Keys);
// Sort them
characters.Sort((x, y) => frequencies[x].CompareTo(frequencies[y]));
input.GroupBy(x => x).OrderByDescending(x => x.Count()).Select(group => group.Key).ToArray();

The information is all there, just don't throw it away:

Dictionary<char, int> count =
  input.GroupBy(g => g).ToDictionary(g => g.Key, g => g.Count());

Oh, right, you just want the characters, not their frequency. Then you have to throw away some of the information:

char[] chars =
  input.GroupBy(g => g).OrderByDescending(g => g.Count()).Select(g => g.Key)
  .ToArray();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top