Rahmat Cahyo
Rahmat Cahyo

Reputation: 25

ask : random string without repitition c#

I have a problem with my code. I want to have string output without repetitions. I have stuck here for 1 week.

I have already tried RemoveAdd but I am still getting an error.

This is my code

public void StringRandom()
{
    Random bsd = new Random();

    string[] femalePetNames = { "Maggie", "Penny", "Saya", "Princess", 
                                "Abby", "Laila", "Sadie", "Olivia", 
                                "Starlight", "Talla" };
    int fIndex = bsd.Next(0, femalePetNames.Length);
    txttBox2.Text = femalePetNames[fIndex];
}

One output is the following: laila,sadie,laila, olivia........ (repetition)

Hope you guys can give me any help. Thanks

UPDATE ------------------------------------------------------------------------------

i just try solution from Marty Thompson and some code could be litle error . But i have try to fix it and YESSS that output have string random without repetition. Big thanks for Matty Thompson and all you guys

This is new correct code

List<string> femalePetNames = new List<string> { "Maggie", "Penny", "Saya", "Princess", 
                    "Abby", "Laila", "Sadie", "Olivia", 
                    "Starlight", "Talla" };

private  void Button_Click(object sender, RoutedEventArgs e)
{
if (femalePetNames.Count > 0)
   {
    Random bsd = new Random();

    int fIndex = bsd.Next(0, femalePetNames.Count);
    txtbox.Text = femalePetNames[fIndex];
    femalePetNames.RemoveAt(fIndex);
   }
}

Upvotes: 1

Views: 2347

Answers (5)

Rahmat Cahyo
Rahmat Cahyo

Reputation: 25

i just try solution from Marty Thompson and some code could be litle error . But i have try to fix it and YESSS that output have string random without repetition. Big thanks for Matty Thompson and all you guys

This is new correct code

List<string> femalePetNames = new List<string> { "Maggie", "Penny", "Saya", "Princess", 
                        "Abby", "Laila", "Sadie", "Olivia", 
                        "Starlight", "Talla" };

    private  void Button_Click(object sender, RoutedEventArgs e)
    {
    if (femalePetNames.Count > 0)
       {
        Random bsd = new Random();

        int fIndex = bsd.Next(0, femalePetNames.Count);
        txtbox.Text = femalePetNames[fIndex];
        femalePetNames.RemoveAt(fIndex);
       }
    }

Upvotes: 0

Rik
Rik

Reputation: 29243

What you're basically asking for is array shuffling. You can create a randomly ordered IEnumerable, like this:

Random r;
// Make sure r is initialized properly at some point
femalePetNames.OrderBy( x=> r.Next() ) 

You should probalby declare your array outside of your method. You can then create a method that supplies a name from the randomly ordered IEnumerable every time it's called:

string[] femalePetNames = { "Maggie", "Penny", "Saya", "Princess", 
                                "Abby", "Laila", "Sadie", "Olivia", 
                                "Starlight", "Talla" };

IEnumerator<string> randomNameEnumerator;
Random r = new Random();

public string NonRepeatingName()
{
    if (randomNameEnumerator == null || !randomNameEnumerator.MoveNext())
    {
        randomNameEnumerator = femalePetNames.OrderBy( x=> r.Next()).GetEnumerator();
        randomNameEnumerator.MoveNext();
    }
    return randomNameEnumerator.Current;
}

You can then assign the names to your textboxes like this:

void Main()
{
    textBox1.Text = NonRepeatingName();
    textBox2.Text = NonRepeatingName();
    textBox3.Text = NonRepeatingName();
    // ...
    textBoxN.Text = NonRepeatingName();
}

Upvotes: 0

plinth
plinth

Reputation: 49179

Take your names and shuffle them with an FYK shuffle (modified slightly - this version takes an array and modifies it):

    public static T[] Shuffle<T>(this T[] arr)
    {
        System.Random rng = new System.Random();
        int n = arr.Length;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            T value = arr[k];
            arr[k] = arr[n];
            arr[n] = value;
        }
        return arr;
    }

Test code:

        string[] femalePetNames = { "Maggie", "Penny", "Saya", "Princess", 
                            "Abby", "Laila", "Sadie", "Olivia", 
                            "Starlight", "Talla" };

        foreach (string s in femalePetNames.Shuffle())
        {
            Console.WriteLine(s);
        }

Output:

Starlight
Princess
Saya
Maggie
Penny
Laila
Talla
Olivia
Abby
Sadie

Upvotes: 0

YtramX
YtramX

Reputation: 180

You're going to have to maintain the state of the collection outside of the scope of this method. The main change is to move the declaration of the femalePetNames collection and remove the element after outputting it.

    List<string> femalePetNames = { "Maggie", "Penny", "Saya", "Princess", 
                            "Abby", "Laila", "Sadie", "Olivia", 
                            "Starlight", "Talla" };
    public void StringRandom()
    {
        if (femalePetNames.Count > 0)
        {
            Random bsd = new Random();

            int fIndex = bsd.Next(0, femalePetNames.Count);
            txttBox2.Text = femalePetNames[fIndex];
            femalePetNames.RemoveAt(fIndex);
        }
    }

I also changed it to a List to use the easily available RemoveAt method. If that's not an option for some reason, you'll need to look at how to remove items from normal arrays.

Upvotes: 0

juharr
juharr

Reputation: 32266

You most likely want something that will define the collection and the Random outside of the method. Where exactly is really not obvious from what you have shown us, but the main point is that the collection must persist between calls to the method for RemoveAt to work.

List<string> femalePetNames = { "Maggie", "Penny", "Saya", "Princess", 
                                "Abby", "Laila", "Sadie", "Olivia", 
                                "Starlight", "Talla" };
Random bsd = new Random();

public void StringRandom()
{   
    if(femalePetNames.Length == 0)
    {
        // Do something here to handle when you've used all the pet names.
    }

    int fIndex = bsd.Next(0, femalePetNames.Length);
    txttBox2.Text = femalePetNames[fIndex];
    femalePetNames.RemoveAt(fIndex);
}

Upvotes: 2

Related Questions