Random letters sorted by sorted list C#

307 Views Asked by At

I have to generate randomly letters in a string

this.text = "";
Random rndChar = new Random();

for (int i = 0; i < 50; i++)
{
    this.text = this.text + (char)rndChar.Next(65,91);
}

The result is something about GUHZBVUTSUZHBF...

Now i have to generate a list of the characters in ascending order with the number of times each character has been repeated. I tried it with

SortedList letters = new SortedList();
for(int i = 0; i < 50; i++)
{
    letters.Add(this.text[i], i);
}

foreach (Char entry in letters.Values)
    Console.WriteLine(entry);

, but that doesn't work:

"System.ArgumentException: 'Item has already been added. Key in dictionary: 'J' Key being added: 'J'' ."

What does that mean? How can i solve that issue?

1

There are 1 best solutions below

0
On

As noted in the comments, the reason SortedList causes a problem here is that it's actually a dictionary, despite the name. You can't call Add with the same key twice. (You can use the indexer to set a new value for a key, whether it previously existed or not, but Add checks whether there's already a value for the key.)

You could use SortedList for its sortedness, but keep the count in the value. That's harder than it needs to be though. I would use LINQ for this - it makes it very easy to do both aspects of this.

var orderedGroups = text
   .GroupBy(c => c, (c, g) => new { Letter = c, Count = g.Count() })
   .OrderBy(g => g.Key);

foreach (var element in orderedGroups)
{
    Console.WriteLine(element);
}

It also makes it easier to do the first part, actually - no need for a for loop and string concatenation. Here's a complete example:

using System;
using System.Linq;

public class Program
{
    static void Main()
    {
        Random rng = new Random();
        var letters = Enumerable.Range(0, 50)
            .Select(_ => (char) rng.Next(65,91))
            .ToArray();

        Console.WriteLine($"Letters: {new string(letters)}");
        var orderedGroups = letters
            .GroupBy(c => c, (c, g) => new { Letter = c, Count = g.Count() })
            .OrderBy(g => g.Key);

        foreach (var element in orderedGroups)
        {
            Console.WriteLine(element);
        }
    }
}