0

EDIT: This does not have to do with randomising numbers. When I tried doing that all I got back was numbers, and not my strings. Could someone at least explain how the Fisher-Yates-shuffle or what it was, would work in my case, if it does actually work for sentences-strings? Because I don't understand it.. I can't be the only one who doesn't understand it?

I have an array of strings that I want to randomise. I want three random strings, that aren't the same, but everything I find online is either for numbers or in another language. At the moment my strings are being randomised, but I sometimes get the same strings, so for example: "Behind a tree, behind a tree, behind a tree".

So it should be like randomHiding1 != randomHiding 2 && randomHiding3; (I know that's not "real code", but just so you get what I mean)

This is my first post here, so I hope this is ok to ask because I haven't been able to find anyone asking a question about randomising "sentences-strings", and not just "abcdefg...." or numbers. Here's my code. Thanks in advance!

    Random random = new Random();

    // strings with hiding spots
        string[] hidingSpot = {
            "in a ditch",
            "up in a tree",
            "behind a stone",
            "in a hole in the ground",
            "behind a tree",
            "in the shadows" };

        int hidingChoice1 = random.Next(hidingSpot.Length);
        int hidingChoice2 = random.Next(hidingSpot.Length);
        int hidingChoice3 = random.Next(hidingSpot.Length);

        string randomHiding1 = hidingSpot[hidingChoice1];
        string randomHiding2 = hidingSpot[hidingChoice2];
        string randomHiding3 = hidingSpot[hidingChoice3];

BTW, I know this code is very bad, and unnecessarily long, but I'm still fairly new to arrays and lists and so my number 1 priority is to get code that works, not code that is short etc. So I don't need tips about reading the documentation, because I am doing that constantly, but I just have a hard time remember things atm due to personal reasons.. I hope that makes sense.

paupau
  • 9
  • 4
  • oh look, there's my answer to the duplicate. http://stackoverflow.com/a/7913534/659190 – Jodrell Feb 17 '16 at 14:39
  • But those are with numbers? Does it still work the same? Because when I tried something similar to that I just got random numbers back, and not my strings. – paupau Feb 17 '16 at 14:41
  • @paupau Have a read up on [generics](https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx). Generics mean the answer doesn't change whether you're randomising strings, ints, dates, or whatever. – Tim Rogers Feb 17 '16 at 14:45
  • Like I wrote in my text, I can't remember/understand documentation that well atm. It's too heavy. I thought someone could explain it briefly with "normal" words, and not so complex as the documentations? – paupau Feb 17 '16 at 14:48
  • @paupau Try the code in the provided answer. You will find that you can pass in an array of strings - when you do, the compiler will replace the type `T` in the method with `string`. You can then just take the first *n* items from the randomised array. There are also plenty of other tutorials on generics that are worth reading. – Tim Rogers Feb 17 '16 at 14:52
  • @paupau See my answer – Fᴀʀʜᴀɴ Aɴᴀᴍ Feb 17 '16 at 14:52

2 Answers2

0

Maybe this could help you: Fisher-Yates Shuffle

Stefan Schmid
  • 1,012
  • 10
  • 28
0

An approach using LINQ:

Random r = new Random();
string[] hidingSpot = "in a ditch|up in a tree|behind a stone|in a hole in the ground|behind a tree|in the shadows".Split('|');
hidingSpot = hidingSpot.OrderBy(x => r.Next()).ToArray();
string one = hidingspot[0];
string two = hidingspot[1];
string three = hidingspot[2];

Finally:

As mentioned in the other answer by Stefan Schmid, you can implement the Fisher-Yates Shuffle a.k.a Knuth Shuffle. An implementation is provided here, which I copy-paste below but all credits go to Jodrell:

public static IEnumerable<T> Shuffle<T>(
        this IEnumerable<T> source,
        Random generator = null)
{
    if (generator == null)
    {
        generator = new Random();
    }

    var elements = source.ToArray();
    for (var i = elements.Length - 1; i >= 0; i--)
    {
        var swapIndex = generator.Next(i + 1);
        yield return elements[swapIndex];
        elements[swapIndex] = elements[i];
    }
}

You can then use this:

hidingSpot = hidingSpot.Shuffle().ToArray();
string one = hidingspot[0];
string two = hidingspot[1];
string three = hidingspot[2];
Fᴀʀʜᴀɴ Aɴᴀᴍ
  • 6,131
  • 5
  • 31
  • 52
  • Thank you!! Is it too much to ask for an explanation of the Shuffle? I'm having a hard time understanding all of the IEnumerable, , the generator and source and elements and swapIndex etc. It's a bit more complex than what I can do and understand atm, and I really do want to understand it! – paupau Feb 17 '16 at 14:55
  • @paupau See [this part](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle#Fisher_and_Yates.27_original_method) of the Wikipedia article. – Fᴀʀʜᴀɴ Aɴᴀᴍ Feb 17 '16 at 14:58
  • I tried your first approach now, which didn't work. And then I tried your second approach using LINQ, and this seems to work. I don't understand how, though. What does this part do? Everything else I understand. And I understand that we "change" it to an array at the end, but what does the x and arrow and orderBy do?hidingSpot.OrderBy(x => r.Next()).ToArray(); – paupau Feb 17 '16 at 15:15
  • @paupau how didn't it work? I mean, how do you conclude that it is wrong? – Fᴀʀʜᴀɴ Aɴᴀᴍ Feb 17 '16 at 15:21
  • I tried it about 10 times, and sometimes it was working, but a couple of times I got the same answers, for example "in the shadows, behind a tree, behind a tree" or even all three being the same. Whereas with the second approach I have now tried it about 20 times and it has never had a duplicate, so SO FAR, it seems to be working. I don't know how else to check it. – paupau Feb 17 '16 at 15:23
  • http://www.dotnetperls.com/orderby and https://msdn.microsoft.com/library/bb534966(v=vs.100).aspx – Fᴀʀʜᴀɴ Aɴᴀᴍ Feb 17 '16 at 15:31