I have a method that accepts as argument an array of integers and I'd just change arbitrary the order of its values
public static int[] _game_number = new int[4];
public static int[] _current_number = new int[4];
public static void GetRandomTwentyFour()
{
HashSet<int> nums = new HashSet<int>();
for (int i = 0; i < 4; i++)
{
Random r = new Random();
nums.Add(r.Next(0, 4));
}
List<int> liste = nums.ToList<int>();
_current_number = new int[] { _game_number[liste[0]], _game_number[liste[1]], _game_number[liste[2]], _game_number[liste[3]] };
}
The problem is that the nums
's elements count is not always four.
- So, How can I modify my snippet to accomplish my task?
- Is there another way to do this?
If you want to reorder them randomly, simply use OrderBy with a random thing as the selector.
Usually you can use Random.Next()
public static int[] _game_number = new int[4];
public static int[] _current_number = new int[4];
private static Random random = new Random();
public static void GetRandomTwentyFour()
{
_current_number = _game_number.OrderBy(r => random.Next()).ToArray();
}
But a new Guid
would work here too², and save you a private field :
public static int[] _game_number = new int[4];
public static int[] _current_number = new int[4];
public static void GetRandomTwentyFour()
{
_current_number = _game_number.OrderBy(g => new Guid()).ToArray();
}
²Please note that Guids are not made to be "random", but to be "unique". However, as you're probably not making an extremely official application (banking, online poker, etc.) it's fair to use it IMO. For an application where the randomness is very important, the RandomNumberGenerator from Cryptography namespace would be a better bet.
You can do something like this
public static int[] GetRandomTwentyFour(int[] _game_number)
{
int len = _game_number.Length;
int[] _current_number = new int[len];
List<int> nums = new List<int>();
Random r = new Random();
for (int i = 0; i < len; i++)
{
int rand = r.Next(0, len);
if (nums.Contains(rand))
{
i = i - 1;
continue;
}
else
nums.Add(rand);
}
for (int i = 0; i < nums.Count; i++)
_current_number[i] = _game_number[nums[i]];
return _current_number;
}
Here is the proof
What about extension method?
public static class ArrayExtensions
{
private static Lazy<Random> random = new Lazy<Random>(() => new Random());
public static IEnumerable<T> GetReorderedElements<T>(this T[] input)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
var rnd = random.Value;
var nums = input.ToList();
var repeats = unusedNums.Length;
while (repeats > 0)
{
var index_first = rnd.Next(0, nums.Length);
var index_second = rnd.Next(0, nums.Length);
var temp = nums[index_first];
nums[index_first] = nums[index_second];
nums[index_second] = temp;
repeats -= 1;
}
return new ReadOnlyCollection(nums);
}
public static T[] GetReorderedElementsAsArray<T>(this T[] input)
{
return GetRandomElements(input).ToArray();
}
}
Usage:
_current_number = _game_number.GetReorderedElementsAsArray();
Well, just change the 4
to a variable holding the number of elements.
While you're at it, you can organize things a bit. Have your GetRandom...
method receive the array, check its size (instead of assuming it's 4) and either shuffling it in place if it's something you want, or returning a new array with the same size.