1

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);
   }
}
  • How do you call this `StringRandom` method? It _might_ generate same results. There is no guarantee to prevent this behaviour. – Soner Gönül Nov 13 '14 at 14:33
  • 2
    What have you tried to ensure there are no duplicates? I see nothing in your code for that. – Jeffrey Wieder Nov 13 '14 at 14:33
  • 2
    @JeffreyWieder, perhaps the OP is of the (mistaken) opinion that true randomness will never duplicate an entry before repeating. – Kirk Woll Nov 13 '14 at 14:34
  • Your code always gets items from the same set. You need to delete item from the set after it was selected. – ttaaoossuuuu Nov 13 '14 at 14:35
  • I assume you mean you tried `RemoveAt` if so, please post that code as well. Most likely the issue is that you are recreating the same list every time this method is called. – juharr Nov 13 '14 at 14:36
  • Maybe the problem is that `bsd` is created with the same seed every time the method is called. Try to move `Random bsd = new Random();` out of the method's body to the class constructor. – undermind Nov 13 '14 at 14:40
  • possible duplicate of [Access random item in list](http://stackoverflow.com/questions/2019417/access-random-item-in-list) – Sam Hanley Nov 13 '14 at 14:50
  • This is what you need, array shuffling: http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp – Larry Nov 13 '14 at 14:50

5 Answers5

2

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);
}
juharr
  • 31,741
  • 4
  • 58
  • 93
0

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();
}
Rik
  • 28,507
  • 14
  • 48
  • 67
  • 1
    This is the shortest array shuffling code I have ever seen. – Larry Nov 13 '14 at 14:50
  • For the current scenario it's fine, but `Guid`s are meant to be unique, _not_ random. So shuffling using that is not a good idea for any serious use, it's better to go with `x => random.Next()` – Pierre-Luc Pineault Nov 13 '14 at 14:53
  • Replaced `Guid` with `Random`. That does make it a little longer, though ;) – Rik Nov 13 '14 at 15:19
0

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.

YtramX
  • 172
  • 10
  • Hey Rahmat, can you vote up the answer? It's the only way newbies like us can get any rep ;) – YtramX Nov 13 '14 at 21:49
0

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
Community
  • 1
  • 1
plinth
  • 48,267
  • 11
  • 78
  • 120
0

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);
       }
    }