0

I have two arrays called numbers and sounds. My code is below. When I use random generator, I don't want the same value to be assigned to the sounds array. sounds[0], sounds[1], sounds[3] should have different values all the time. Thanks

string[] numbers ={ "1", "2", "3", "4", "5", "6", "7","8","9","10","11","12","13","14","15","16","17","18","19","20"};

Random r= new Random();

sounds[0] = numbers[r.Next(0, numbers.Count())];

sounds[1] = numbers[r.Next(0, numbers.Count())];

sounds[2] = numbers[r.Next(0, numbers.Count())];
Adil
  • 146,340
  • 25
  • 209
  • 204
user2569038
  • 33
  • 1
  • 8
  • What is the problem exactly? Or what does it generate now – Tim Jul 22 '13 at 13:50
  • Really don't get what purpose numbers serves, you could just have r.Next(1, 20) – Sayse Jul 22 '13 at 13:52
  • When I compile the program the values of sounds[0], sounds[1], sounds[3] could be the same value. For example sounds[0]=5 , sounds[1]=5, sounds[3]=20. sounds[0] and sounds[1] have the same value in here for instance. I want them to be different values. – user2569038 Jul 22 '13 at 13:53
  • Let it generate a number, if its not already in `sounds` great, if it is, generate a new number for that position – Tim Jul 22 '13 at 13:56
  • This isn't exactly a duplicate because it sounds like he just wants a subset of the larger array, rather than a shuffled array. I posted an answer anyway. – Gray Jul 22 '13 at 14:14
  • 1
    @Gray There are several approaches to solving the problem of getting a subset of random unique values from a list; one valid approach is to shuffle the list and then take the first N values from the list. Whether it's preferable or not to the option of taking items and seeing if you've already taken it depends on the size of the collection and the number of items you plan to take. If you want a small percentage of the items it's better to guess and check, for a large percentage you're better off shuffling the whole thing. – Servy Jul 22 '13 at 14:16
  • @Servy I agree 100%, it is important that that is clear to the asker. Thanks – Gray Jul 22 '13 at 14:20

2 Answers2

0

If you want a simple approach and performance is not an issue, you could convert your array into a list and remove each element as it is taken:

string[] numbers ={ "1", "2", "3", "4", "5", "6", "7","8","9","10","11","12","13","14","15","16","17","18","19","20"};

List<string> remaining = new List<string>(numbers);

Random r = new Random();

for (int i = 0; i < 3; ++i)
{
    int n = r.Next(0, remaining.Count);
    sounds[i] = remaining[n];
    remaining.RemoveAt(n);
}
Douglas
  • 53,759
  • 13
  • 140
  • 188
0

Here is a rather simple/naive answer that may give you some ideas. Note that you should probably use .Length rather than .Count() since .Length is an O(1) operation, and you already have the property there. This solution doesn't scale if sounds is bigger. If that's the case, you'll want to shuffle the numbers array. This will give you three unique values though.

string[] numbers = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" };
string[] sounds = new string[3];
Random r = new Random();

//get the first one, this one will always be unique
sounds[0] = numbers[r.Next(0, numbers.Length)];
//set the second equal to the first, so that it will enter the while loop.
sounds[1] = sounds[0];
while (sounds[1] == sounds[0]) //repeats until it gets a unique value
    sounds[1] = numbers[r.Next(0, numbers.Length)]; 
sounds[2] = sounds[0]; 
while (sounds[2] == sounds[1] || sounds[2] == sounds[0]) //works the same as previous, except it checks for both
    sounds[2] = numbers[r.Next(0, numbers.Length)];
Gray
  • 7,050
  • 2
  • 29
  • 52