Generate a random string that wasn't previously generated c#

Hemanth B 886 Reputation points
2021-08-25T15:03:47.763+00:00

Hi, I want to generate random strings out of a list: So I used this code:
Random rnd = new Random();
List<string> validStrings = new List<string>() {
"Banana",
"Avocado",
"Grape",
"Apple", "Custard Apple",
"Cranberry" };
result = validStrings[rnd.Next(0, validStrings.Count)];
But I want it to generate only if that string wasn't previously already generated. So I tried using a listbox:

 private void GenerateRandom()
        {
            try
            {
                Random rnd = new Random();
                List<string> validStrings = new List<string>() {
                   "Banana",
                    "Avocado",
                   "Grape",
                   "Apple", "Custard Apple",
                "Cranberry" };
                result = validStrings[rnd.Next(0, validStrings.Count)];
                if (!listBox1.Items.Contains(result))
                {
                    generatedrandom = result;

                    listBox1.Items.Add(result);


                }
                else
                {

                    GenerateRandom();
                }
            }
            catch (Exception EX)
            {
                MessageBox.Show(EX.ToString(), "EXCEPTION");
            }

But I get this exception: System.StackOverflowException
I understood that it infinitely looped the code and finally wasn't able to generate anything.

Please help

Developer technologies C#
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 122.5K Reputation points
    2021-08-25T15:28:40.643+00:00

    Move the ‘Random rnd = new Random()’ line to class (form) level. This will solve one of issues.

    In addition, make sure that the list box is not full, for example:

    if( listBox1.Items.Count >= validStrings.Count)
    {
       // no more valid strings
       return;
    }
    

    Check an alternative function too:

    static readonly Random rnd = new Random( );
    static readonly List<string> validStrings = new List<string>
    {
       "Banana",
       "Avocado",
       "Grape",
       "Apple",
       "Custard Apple",
       "Cranberry"
    };
    
    private bool GenerateRandom( )
    {
       var unused_strings = validStrings.Except( listBox1.Items.Cast<string>( ) ).ToArray( );
    
       if( unused_strings.Length == 0 ) return false;
    
       string generated = unused_strings[rnd.Next( unused_strings.Length )];
    
       listBox1.Items.Add( generated );
    
       return true;
    }
    
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Sam of Simple Samples 5,546 Reputation points
    2021-08-25T19:31:21.47+00:00

    The trick is to remove each item from the list after having gotten it. First, yes, you need to do the new Random() only once each time. The other problem is that there is no need for recursion.

    The following will generate a new list each time a button is pushed. Complete sample in Answers/GenerateRandom.

    public partial class Form1 : Form
    {
        string[] validStrings = new string[] {
            "Banana",
            "Avocado",
            "Grape",
            "Apple",
            "Custard Apple",
            "Cranberry"
            };
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            Random rnd = new Random();
            List<string> unchosen = new List<string>(validStrings);
            while (unchosen.Count > 0)
                GenerateRandom(unchosen, rnd);
        }
    
        private void GenerateRandom(List<string> unchosen, Random rnd)
        {
            try
            {
                string result = unchosen[rnd.Next(0, unchosen.Count)];
                unchosen.Remove(result);
                listBox1.Items.Add(result);
            }
            catch (Exception Ex)
            {
                MessageBox.Show($"Error: {Ex.Message}");
            }
        }
    }
    
    0 comments No comments

  2. Jack J Jun 25,296 Reputation points
    2021-08-26T02:04:55.577+00:00

    @Hemanth B , the exceptions means that your program are stuck in the Infinite loop when your listBox1 has the same elements with list validStrings .

    Therefore, we need to jump out of the loop when we face the problem.

    Here is a code example you could refer to.

    public void GenerateRandom()  
            {  
                try  
                {  
                    Random rnd = new Random();  
                    List<string> validStrings = new List<string>() {  
                        "Banana",  
                         "Avocado",  
                        "Grape",  
                        "Apple", "Custard Apple",  
                     "Cranberry" };  
                    string generatedrandom = "";  
                    var result = validStrings[rnd.Next(0, validStrings.Count)];  
                    if (!listBox1.Items.Contains(result))  
                    {  
                        generatedrandom = result;  
      
                        listBox1.Items.Add(result);  
      
                    }  
                    else if(listBox1.Items.Count==validStrings.Count)            //Added code here  
                    {  
                        MessageBox.Show("The list is filled with random string");  
                        return;  
                    }  
                    else  
                    {  
                        GenerateRandom();  
                    }  
                }  
                catch (Exception EX)  
                {  
                    MessageBox.Show(EX.ToString(), "EXCEPTION");  
                }  
            }  
      
            private void button1_Click(object sender, EventArgs e)  
            {  
                GenerateRandom();  
            }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.