Re-ordering arbitrary an array of integers

穿精又带淫゛_ 提交于 2020-01-11 07:58:06

问题


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?

回答1:


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.




回答2:


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




回答3:


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();



回答4:


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.



来源:https://stackoverflow.com/questions/25106133/re-ordering-arbitrary-an-array-of-integers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!