如何在 C# 中以相同的方式随机化/洗牌两个数组
Posted
技术标签:
【中文标题】如何在 C# 中以相同的方式随机化/洗牌两个数组【英文标题】:How to randomize/shuffle two arrays in the same way in c# 【发布时间】:2022-01-04 03:17:08 【问题描述】:我有两个数组,一个是 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<int, PictureBox>
然后你可以使用随机的int
来访问它们,这是关键。
恕我直言,拥有一个具有PictureBox
和int
属性的类数组会更简洁。
【参考方案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
的实例时,它会在内部创建一个列表或伪随机元素(这里它们是Guid
s,但它可以是随机选择的整数,或者您想要的任何东西)。
要打乱集合,只需将其传递给 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
扩展方法的纯静态类也可以按照相同的原理制作。
【讨论】:
以上是关于如何在 C# 中以相同的方式随机化/洗牌两个数组的主要内容,如果未能解决你的问题,请参考以下文章