Как рандомизировать/перемешать два массива одним и тем же способом в c#

#c# #arrays #random #fisher-yates-shuffle

Вопрос:

У меня есть два массива, один из которых представляет собой массив PictureBox, а другой-массив целых чисел, оба имеют одинаковое количество элементов. Я хочу, чтобы оба массива каждый раз перемешивались случайным образом, но оба перемешивались одинаково.

Вот код, который работает, если я использую два массива PictureBox или два массива целых чисел, однако я хочу, чтобы он перемешал один массив PictureBox и один массив целых чисел.

Вот код, с которым я хочу работать: (два разных массива)

 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 lt; 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 lt; 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;  }  

Если вы знаете другой код, который может помочь мне, не стесняйтесь поделиться им!

Комментарии:

1. Я предлагаю вам сделать Dictionarylt;int, PictureBoxgt; так, чтобы вы могли получить к ним доступ, используя случайный int ключ.

2. ИМХО, иметь один массив класса со PictureBox int свойствами и было бы чище.

Ответ №1:

Просто создайте две временные переменные

 for (int i = 0; i lt; 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 Listlt;Guidgt; order;  private Listlt;Guidgt; createOrder(int count)  {  return Enumerable.Range(0, count)  .Select(i =gt; Guid.NewGuid())  .ToList();  }    public Shuffler(int count)  {  order = createOrder(count);  }    public void Reshuffle()  {  order = createOrder(order.Count);  }    public IEnumerablelt;Tgt; Shufflelt;Tgt;(IEnumerablelt;Tgt; collection)  {  return collection.Zip(order)  .OrderBy(e =gt; e.Second)  .Select(e =gt; e.First);  } }  

Когда вы создаете экземпляр Shuffler , он внутренне создает список или псевдослучайные элементы (здесь они Guid s, но это могут быть случайно выбранные целые числа или все, что вам захочется). Чтобы перетасовать коллекцию, просто передайте ее Shuffle методу. Каждая переданная коллекция будет переупорядочена точно таким же образом.

Его можно было бы улучшить, например, он ожидает, что каждая коллекция будет иметь одинаковое количество элементов, и что это число было передано Shuffler конструктору, это можно было бы ослабить. Там также нет проверки на ошибки, но это должно дать представление о принципе.

Вот пример использования. Вы можете попробовать это в Linqpad.

 void Main() {  // The test collections of different types.  var cards = Enumerable.Range(0, 13)  .Select(i =gt; 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 Listlt;Guidgt; order;  private Listlt;Guidgt; createOrder(int count)  {  return Enumerable.Range(0, count)  .Select(i =gt; Guid.NewGuid())  .ToList();  }    public Shuffler(int count)  {  order = createOrder(count);  }    public void Reshuffle()  {  order = createOrder(order.Count);  }    public IEnumerablelt;Tgt; Shufflelt;Tgt;(IEnumerablelt;Tgt; collection)  {  return collection.Zip(order)  .OrderBy(e =gt; e.Second)  .Select(e =gt; 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 методом расширения также мог быть создан по тому же принципу.