-6

First of all I am not an expert with C#, so I would appreciate answers that are simplied. And thanks in advance..

I have an array with 30 elements all integers and different than each other. I want to make an another array with length of 6. And appoint elements from 30length one to here but i dont want a number to appear more than one. I tried random function which obviously makes it possible to appear same numbers there. I could add statements maybe, but i thought there must be a short way.

I would like to ask you folks if there is, if so please share with me, thanks again.

int [] nums  = new int[30];
for (int i = 0; i < nums.Length; i++)
{
    nums[i] = i + 1;
}

Random rnd = new Random();
int[] card1 = new int[6];
for (int i = 0; i < card1.Length; i++)
{
    card1[i] = nums[rnd.Next(0, 30)];
}
MethodMan
  • 18,625
  • 6
  • 34
  • 52
Alp
  • 367
  • 3
  • 18

4 Answers4

3

So your problem, freely translated is:

I have a sequential, numeric array containing values from 1 through 30. I want to select 6 unique values from this array from random positions.

The accepted solution to this is to properly (e.g. Fisher-Yates) shuffle the array and simply take the number of required elements from the front.

Given you may want to keep your original array in order, you could create a copy and shuffle that.

That'll look like this:

var sourceArray = // your loop, or something like Enumerable.Range(1, 30).ToArray();
var arrayToPickFrom = Shuffle(sourceArray.ToArray()); // make a copy and shuffle it
var randomCards = arrayToPickFrom.Take(6); // take the first six elements 

Alternatively, the question could be simplified:

I want to generate N random, unique numbers between 1 and M.

Which is even less lines of code. But it all depends on your requirements. If you're actually trying to create a card game, where after the initial six cards more cards will be drawn - and a card can only be drawn once, you should approach this problem entirely different, for starters by introducing a Deck class to contain all cards, having convenient methods...

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • 1
    `plus 1 from me exactly what I was thinking myself i noticed you borrowed from my comment` LOL – MethodMan Nov 09 '15 at 18:24
  • Thanks, I guess "Shuffle" is a method as i made a quick search, sorry if i am wrong, I am kinda beginner so i am thinking this will be kinda complicated for me yet. – Alp Nov 09 '15 at 18:29
  • 1
    @Alp yes, it's a method you'll have to implement. There are plenty of implementations on the web if you search for "C# fisher yates shuffle". :) – CodeCaster Nov 09 '15 at 18:29
0

There are other ways to solve this, but since you asked for something simplified I will try not to change your code.

Random rnd = new Random();
var values = new List<int>(nums); // 1

int[] card1 = new int[6];
for (int i = 0; i < card1.Length; i++)
{
    var rand = rnd.Next(0, values.Count); // 2
    card1[i] = values[rand]; // 3
    values.RemoveAt(rand); // 4
}
  1. Create a List from the nums array.
  2. Take a random index;
  3. Copy the element of the created list at that index to card1 array;
  4. Remove the element from the list so you can't copy it again;

I must say that even though this is a simple solution, it is by no means the most "performant" one.

victor
  • 1,532
  • 1
  • 13
  • 32
-1

Why dont you take the first 6 ones?

var theOtherArray = Nums.Take(6).ToArray(); 
The Chris
  • 591
  • 6
  • 19
-1

A simple solution:

int[] card1 = nums.OrderBy(it => Guid.NewGuid()).Take(6).ToArray();

Ordering the original array by a new guid should give you a decent approximation of randomness while avoiding the requirement to explicitly guard against duplication.

Then you just take the first 6 results.

Warning: The random-like behaviour of ordering by guid is an implementation detail of the current Guid.NewGuid() method so it's important not to rely on this functionality - especially in production code.

A better implementation would use a Fisher-Yates shuffle, see for example, this post: https://stackoverflow.com/a/1653204/5438433

Community
  • 1
  • 1
TheInnerLight
  • 12,034
  • 1
  • 29
  • 52
  • excellent example in regards to getting a different number from the `nums` int[] when run different times. – MethodMan Nov 09 '15 at 18:27
  • 2
    `Guid`s are unique, not necessarily random. You should not use the in place of a random number generator. – Servy Nov 09 '15 at 21:58
  • @TheInnerLight That's just not true. A `GUID` is entirely within its rights to return values that are based on a timestamp, which would mean that you'd get monotone increasing values, which would mean the sequence would always be returned in the original order. The GUID algorithm could also change in the future to something completely unknown to us now *that is in no way random*. It's not about the quality of the source of the random number generator, or whether it's cryptographically strong. GUID isn't even trying to be random at all *not even psudorandom*. It's only there to be unique. – Servy Nov 09 '15 at 22:13
  • @Servy I have updated my post to reflect that this isn't a technique that should be relied upon for production code. I think that is both a valid point and information someone reading the post should be aware of. However, I still think this can presently be a useful technique for rapid prototyping. – TheInnerLight Nov 09 '15 at 22:58
  • @TheInnerLight So why post the answer at all if nobody should ever use it? If you know that it shouldn't be used, then don't suggest that people use it. Suggest that they use a technique that they can actually rely on working. The fact that it *seems* to work at first glance, even though you can't rely on it at all, makes it *much worse* as people will test it once, think it does what they want, and then never change it. That's *way* more harmful than something that just doesn't work at all. – Servy Nov 09 '15 at 23:06
  • 1
    @TheInnerLight No one should use it in any program that wants to reliably work. Having something that's only useful for prototyping is just creating a likely bug in the actual product, especially given that an *actual* solution is so trivial. The fact that this is seen all over the place should *incentive you to stop spreading misinformation* rather than encouraging you to cause further harm. Do you actually think that all of the people using this actually realize that they can have no expectation of this actually shuffling and that it's perfectly valid for this code to not change the order? – Servy Nov 09 '15 at 23:15
  • @TheInnerLight - Others on Stack Overflow are equally wrong - those who have proposed a similar answer and those who have accepted it. – Enigmativity Dec 17 '15 at 11:42