【问题标题】:How to randomize/shuffle two arrays in the same way in c#如何在 C# 中以相同的方式随机化/洗牌两个数组
【发布时间】:2025-12-30 00:55:07
【问题描述】:

我有两个数组,一个是 PictureBox 数组,另一个是 Integer 数组,它们都有相同数量的元素。我希望两个数组每次都随机打乱,但都以相同的方式打乱。

如果我使用两个 PictureBox 数组或两个 Integer 数组,这是一个有效的代码,但是我希望它随机播放一个 PictureBox 数组和一个 Integer 数组。

这是我想要工作的代码:(两个不同的数组)

PictureBox[] cards = new PictureBox[13];
// PictureBox[] numValue = new PictureBox[13];
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 };

Random rnd = new Random();

for (int i = 0; i < cards.Length - 1; i++)
{
    int j = rnd.Next(i, cards.Length);

    PictureBox temp = cards[j];
    cards[j] = cards[i];
    cards[i] = temp;

    temp = numbers[j]; //An error occurs here because numbers is not a PictureBox variable
    numbers[j] = numbers[i];
    numbers[i] = temp; 
}

这是有效的代码:(对于相同的数组)

PictureBox[] numValue = new PictureBox[13];
PictureBox[] cards = new PictureBox[13];
// int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 };

Random rnd = new Random();

for (int i = 0; i < cards.Length - 1; i++)
{
    int j = rnd.Next(i, cards.Length);

    PictureBox temp = cards[j];
    cards[j] = cards[i];
    cards[i] = temp;

    temp = numValue [j]; 
    numValue [j] = numValue [i];
    numValue [i] = temp; 
}

如果您知道其他可以帮助我的不同代码,请随时分享!

【问题讨论】:

  • 我建议你创建Dictionary&lt;int, PictureBox&gt; 然后你可以使用随机的int 来访问它们,这是关键。
  • 恕我直言,拥有一个具有PictureBoxint 属性的类数组会更简洁。

标签: c# arrays random fisher-yates-shuffle


【解决方案1】:

只需创建两个临时变量

for (int i = 0; i < cards.Length - 1; i++)
{
    int j = rnd.Next(i, cards.Length);

    PictureBox tempPictureBox = cards[j]; // One for PictureBox
    cards[j] = cards[i];
    cards[i] = tempPictureBox;

    int tempInt = numValue[j]; // Another one for int
    numValue[j] = numValue[i];
    numValue[i] = tempInt; 
}

【讨论】:

    【解决方案2】:

    如果你想要一个可以在任何集合上使用的洗牌器,你可以创建这样一个类。

    public class Shuffler
    {
        private List<Guid> order;
        private List<Guid> createOrder(int count)
        {
            return Enumerable.Range(0, count)
                .Select(i => Guid.NewGuid())
                .ToList();
        }
        
        public Shuffler(int count)
        {
            order = createOrder(count);
        }
        
        public void Reshuffle()
        {
            order = createOrder(order.Count);
        }
        
        public IEnumerable<T> Shuffle<T>(IEnumerable<T> collection)
        {
            return collection.Zip(order)
                .OrderBy(e => e.Second)
                .Select(e => e.First);
        }
    }
    

    当您创建Shuffler 的实例时,它会在内部创建一个列表或伪随机元素(这里它们是Guids,但它可以是随机选择的整数,或者您想要的任何东西)。 要打乱集合,只需将其传递给 Shuffle 方法。每个通过的集合都将以相同的方式重新排序。

    它可以改进,例如它期望每个集合具有相同数量的元素,并且这个数字被传递给Shuffler 构造函数,这可以放宽。也没有错误检查,但它应该给出一个原理的概念。

    这是一个使用示例。你可以在 Linqpad 中试试。

    void Main()
    {
        // The test collections of different types.
        var cards = Enumerable.Range(0, 13)
            .Select(i => new PictureBox { Foo = $"{i}"})
            .ToArray();
        var numbers = Enumerable.Range(0, 13)
            .ToArray();
        
        // Creation of the Shuffler instance
        var shuffler = new Shuffler(cards.Length);
        
        // Using the Shuffler instance to shuffle collections.
        // Any number of collections can be shuffled that way, in the same exact way.
        cards = shuffler.Shuffle(cards).ToArray();
        numbers = shuffler.Shuffle(numbers).ToArray();
        
        // Display results.
        cards.Dump();
        numbers.Dump();
    
        // Perform a new shuffle using the same Shuffler instance.
        shuffler.Reshuffle();
        // Again use the Shuffler to shuffle the collections.
        cards = shuffler.Shuffle(cards).ToArray();
        numbers = shuffler.Shuffle(numbers).ToArray();
    
        // Display results.
        cards.Dump();
        numbers.Dump();
    }
    
    // You can define other methods, fields, classes and namespaces here
    public class PictureBox
    {
        public string Foo { get; set; }
    }
    
    public class Shuffler
    {
        private List<Guid> order;
        private List<Guid> createOrder(int count)
        {
            return Enumerable.Range(0, count)
                .Select(i => Guid.NewGuid())
                .ToList();
        }
        
        public Shuffler(int count)
        {
            order = createOrder(count);
        }
        
        public void Reshuffle()
        {
            order = createOrder(order.Count);
        }
        
        public IEnumerable<T> Shuffle<T>(IEnumerable<T> collection)
        {
            return collection.Zip(order)
                .OrderBy(e => e.Second)
                .Select(e => e.First);
        }
    }
    

    一个结果集:

    cards number
    "12"  12
    "1"   1
    "0"   0
    "11"  11
    "3"   3
    "2"   2
    "9"   9
    "5"   5
    "10"  10
    "8"   8
    "4"   4
    "7"   7
    "6"   6
    

    具有静态字段和Shuffle 扩展方法的纯静态类也可以按照相同的原理制作。

    【讨论】: