4

I have an array like this one:

int[] numbers = new [] { 1, 2, 3, 4 };

I'd like to randomize this (different each time) so that it makes another array with the same size and numbers but in a different order each time.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Dave Heart
  • 61
  • 1
  • 2
  • 4
  • 1
    You can't find an easy way to do that because you're asking for two completely opposite things. "Random" and "a different order each time" are *opposites*. If the process is *random* then you should expect repeats. If you roll dice enough times you expect to see repeats, even if the results are random. You need to more clearly specify what you actually want. Once you have written a clear, correct specification then it will become much easier to find an implementation. – Eric Lippert May 03 '11 at 07:12
  • I think what @Eric is also implying is that it's unclear if you need randomness or simply want to iterate through all permutations of the array. – Michael Stum May 03 '11 at 17:23
  • 1
    @Michael: Exactly. Is what is desired (1) simply a single random permutation of the array, or (2) a random sequence of random permutations of the array, or (3) a random ordering of the sequence of all possible permutations? All three of those are different and the question as it stands is confusing as to which is desired. – Eric Lippert May 03 '11 at 17:51
  • How many times has this been asked on the internet? You must have had related question suggestions when asking the question. – usr Jul 17 '13 at 11:35

6 Answers6

17

Try something like this:

System.Random rnd = new System.Random();
var numbers = Enumerable.Range(1, 4).OrderBy(r => rnd.Next()).ToArray();
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
  • 1
    Excellent, thank you very much. – dpant Aug 11 '17 at 10:17
  • var numbers = Enumerable.Range(1, 4).OrderBy(r => rnd.Next(1,4)).ToArray(); – Unbreakable Apr 21 '18 at 08:53
  • Do we need to add 1,4 in `rnd.Next(min,max)` too? Ideally we need to tell that we need to order by with min and max range in rnd.Next(min,max). Why does your solution works w/o giving any range to `rnd`, please explain – Unbreakable Apr 21 '18 at 08:54
4

Here's a method that will work:

public List<int> Randomize(int[] numbers)
{
    List<int> randomized = new List<int>();
    List<int> original = new List<int>(numbers);
    Random r = new Random();
    while (original.Count > 0) {
        int index = r.Next(original.Count);
        randomized.Add(original[index]);
        original.RemoveAt(index);
    }

    return randomized;
}

Edit:

Another way could be using LINQ extension methods for IEnumerable<T> collections:

var random = new Random();
List<int> randomized = numbers.OrderBy(x => random.Next()).ToList();

If you want to have an array instead of a List<int> you can invoke .ToArray() instead.

Of course, that will work for any array of int, not only for 1, 2, 3, ..., n. You can even make the method generic in T.

Oscar Mederos
  • 29,016
  • 22
  • 84
  • 124
2
public  static void Shuffle<T>(T[] array)
{
    Random random = new Random();

    for (int i = 0; i < 10; i++)
    {
        int idx = random.Next(i, 10);

        //swap elements
        T tmp = array[i];
        array[i] = array[idx];
        array[idx] = tmp;
    }  
}
Marcus Ekström
  • 410
  • 6
  • 11
0

In my eyes the easiest way would be this:

 int[] grid = new int[9];//size of array

        Random randomNumber = new Random();//new random number
        var rowLength = grid.GetLength(0);
        var colLength = grid.GetLength(1);
        for (int row = 0; row < rowLength; row++)
        {

                grid[col] = randomNumber.Next(4)+1;//Fills grid with numbers from
                                                        //1-4
                Console.Write(String.Format("{0}\t", grid[col]));
                //Displays array in console

            Console.WriteLine();
        }
John
  • 115
  • 3
  • 12
0

This even takes care that the values dont repeat ;

for(int i=0;i<4;i++)
{
  int no_repeat = -1;

  int x,j;

  while(no_repeat!=1)
  {
    x=rand()%4;
    for(j=0;j<4;j++)
    {
      if(numbers[j]==x)
        break;
    }

    if(j==4)
      no_repeat=1;


  }

  if(no_repeat)
  numbers[i]=x;
}
koool
  • 15,157
  • 11
  • 45
  • 60
-2

It works:

numbers = numbers.OrderBy(s => Guid.NewGuid()).ToArray();