-1

I want to fill my array with unique random numbers between 0-9 in c# I try this function:

    IEnumerable<int> UniqueRandom(int minInclusive, int maxInclusive)
    {
        List<int> candidates = new List<int>();
        for (int i = minInclusive; i <= maxInclusive; i++)
        {
            candidates.Add(i);
        }
        Random rnd = new Random();
        while (candidates.Count > 1)
        {
            int index = rnd.Next(candidates.Count);
            yield return candidates[index];
            candidates.RemoveAt(index);
        }
    }

And I use it like this:

for (int i = 0; i < 3; i++)
{
    page[i] = UniqueRandom(0, 9);
}

But I got error :

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<int>' to 'int'

I also added this name space:

using System.Collections.Generic;

I just don't know how I can convert the function output to int... please help me... thank you...

Matt Tester
  • 4,663
  • 4
  • 29
  • 32
Nimait70
  • 25
  • 2
  • 3
  • 5

4 Answers4

4

You're much better off doing something like this, using a Fischer-Yates shuffle:

public static void Shuffle<T>(this Random rng, IList<T> list)  
{  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}

Usage:

var numbers = Enumerable.Range(0, 10).ToList(); // 0-9 inclusive
var rng = new Random();
rng.Shuffle(numbers);
int[] page = numbers.Take(3).ToArray();
dtb
  • 213,145
  • 36
  • 401
  • 431
Dave Bish
  • 19,263
  • 7
  • 46
  • 63
  • @dtb Why did you change this, to be an extension on Random()? – Dave Bish May 21 '12 at 15:33
  • 4
    To avoid [a common pitfall](http://stackoverflow.com/questions/767999) when using the Random class. – dtb May 21 '12 at 15:34
  • 2
    If you create the Random instance inside the method then you get the same result when you call it multiple times closely in succession. You have to use the same Random instance across multiple calls to get random results. – dtb May 21 '12 at 15:37
  • I just thought I'd mention that this algorithm lends itself nicely to yielding each result as it is picked (in addition to swapping the positions in the array) which would allow you to get, for example, 3 unique items from a set of 10 without needing to shuffle the whole array. All you'd need to do is change the return type and add a `yield return` at the end of the while loop. Making this change would also affect the usage of the method. – Servy May 21 '12 at 15:43
2

Your method returns an enumerable, but you try to assign a single value. Assign all the values in one step:

int[] page = UniqueRandom(0, 9).Take(3).ToArray();  // instead of your loop

EDIT: From your comments, I judge that you might have copied the code you have shown us without understanding it. Maybe you want to fill your array with random numbers with repetitions possible (e.g. 1, 6, 3, 1, 8, ...)? Your current code only uses each value once (hence the name unique), so you cannot fill an array of size larger than 10 with it.

If you just want simple random numbers, there's no need for this method at all.

var rnd = new Random();

// creates an array of 100 random numbers from 0 to 9
int[] numbers = (from i in Enumerable.Range(0, 100) 
                 select rnd.Next(0, 9)).ToArray();
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • what if i want to filling my array(array size = 100) with random number between 0-9...also i dont want to all my array room filling with same number – Nimait70 May 22 '12 at 07:13
  • @Nimait70: This code won't fill your array with the same number, it will fill it with three different numbers. I don't understand your question about array size 100: There are only 10 *unique* numbers from 0 to 9. How can you fill up an array of size 100 with them? (You'd go, e.g. `{5, 2, 7, 4, 1, 3, 0, 8, 9, 6, ... ` and then you're out of unique numbers!) – Heinzi May 22 '12 at 07:17
  • @Nimait70: I've changed my answer, please check if it applies to your question. – Heinzi May 22 '12 at 07:23
  • @Nimait70: Glad to hear that. If your question has been answered, please mark one answer with the "check" button, see here for details: http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Heinzi May 22 '12 at 08:09
  • @Heinzi: Where does "UniqueRandom" come from? I tried inputting that into my code and it says "The name 'UniqueRandom' does not exist in the current context" – Marshal Nov 05 '12 at 15:48
1

You could do this:

int i = 0;
foreach (int random in UniqueRandom(0, 9).Take(3))
{
    page[i++] = random;
}
David M
  • 71,481
  • 13
  • 158
  • 186
0

my array is too big, i need many random numbers...and when i used

 int[] page = UniqueRandom(0, 9).Take(arraysize).ToArray(); 

it gave me exactly 9 unique random numbers..

and i got this error(for example for arraysize = 15) :

index was outside of bounds of array

how i can have a array with too many random numbers between 0-9 without repeat?

Nimait70
  • 25
  • 2
  • 3
  • 5
  • This doesn't make sense, you can only have 10 unique numbers between 0-9 because that's... 10 numbers. What are you trying to accomplish? – Mike Park May 22 '12 at 06:38
  • @climbage : i want array with too many random numbers between 0-9 without repeat all the time...it's ok to repeat sometimes but i dont want to all my array room filling with same number – Nimait70 May 22 '12 at 07:06
  • @Nimait70 -- I'm a little confused here. Did you mean to add this to your question? This doesn't look like an answer to me. You are able to edit your question. – Bob Kaufman May 22 '12 at 14:06