You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中从现有数组创建随机排序的新数组?

Hey there! 看你想要基于现有数组生成一个随机排序的新数组,同时保留原数组的顺序对吧?结合你给出的代码,我给你两种实用的实现方案:


你的需求与现有代码:
我希望从现有的数组创建一个随机排序的新数组,即将原数组的元素以随机顺序复制到新数组中。以下是我的现有代码:

MobileObjects[] array = new MobileObjects[3]; 
MobileObjects mob = new MobileObjects(); 
mob.name = ("Jawaharal"); 
mob.setPosition(); 
mob.id = 1; 
array[0] = mob; 

MobileObjects mob1 = new MobileObjects(); 
mob1.name = ("Willow"); 
mob1.setPosition(); 
mob1.id = 2; 
array[1] = mob1; 

MobileObjects mob2 = new MobileObjects(); 
mob2.name = ("Indira"); 
mob2.id = 3; 
mob2.setPosition(); 
array[2] = mob2; 

//shows whats in array 
foreach (MobileObjects host in array) { 
    Console.WriteLine("Name : " + host.name + " "); 
    Console.WriteLine("ID : " + host.id); 
    Console.WriteLine("Position: " + host.position[0] + " " + host.position[1] + " " + host.position[2]); 
}

方案1:用LINQ快速实现(适合小型数组)

这个方法代码简洁,上手快,适合数组元素不多的场景:

// 保留你原有的数组初始化代码
MobileObjects[] array = new MobileObjects[3];
// ... 你的初始化代码省略 ...

// 关键:生成随机排序的新数组
Random rng = new Random();
MobileObjects[] shuffledArray = array.OrderBy(item => rng.Next()).ToArray();

// 验证随机排序后的结果
foreach (MobileObjects host in shuffledArray)
{
    Console.WriteLine("Name : " + host.name);
    Console.WriteLine("ID : " + host.id);
    Console.WriteLine("Position: " + host.position[0] + " " + host.position[1] + " " + host.position[2]);
}

说明:

  • OrderBy(item => rng.Next())会给每个元素分配一个随机整数,然后根据这个整数排序,每次运行都会得到不同的顺序。
  • ToArray()会生成一个全新的数组,原数组的元素顺序完全不受影响,完美符合你的需求。
  • 记得提前添加using System.Linq;引用,不然LINQ方法会报错。

方案2:Fisher-Yates洗牌算法(高效首选)

如果你的数组元素较多,这个算法的效率更高(时间复杂度O(n)),而且是行业内公认的标准洗牌方案:

// 保留你原有的数组初始化代码
MobileObjects[] array = new MobileObjects[3];
// ... 你的初始化代码省略 ...

// 第一步:复制原数组到新数组,避免修改原数组
MobileObjects[] shuffledArray = (MobileObjects[])array.Clone();
Random rng = new Random();

// 第二步:执行Fisher-Yates洗牌逻辑
int length = shuffledArray.Length;
while (length > 1)
{
    length--;
    // 生成随机索引
    int randomIndex = rng.Next(length + 1);
    // 交换元素位置
    MobileObjects temp = shuffledArray[randomIndex];
    shuffledArray[randomIndex] = shuffledArray[length];
    shuffledArray[length] = temp;
}

// 验证随机排序后的结果
foreach (MobileObjects host in shuffledArray)
{
    Console.WriteLine("Name : " + host.name);
    Console.WriteLine("ID : " + host.id);
    Console.WriteLine("Position: " + host.position[0] + " " + host.position[1] + " " + host.position[2]);
}

说明:

  • 我们先用array.Clone()复制原数组,这样原数组的顺序完全不变,洗牌操作只在新数组上进行。
  • Fisher-Yates算法通过原地交换元素实现随机排序,没有额外的排序开销,比LINQ的OrderBy更高效。

重要注意事项
  • 不要在循环内创建Random实例:如果在循环里每次都new Random(),会因为系统时钟的精度问题生成重复的随机数,导致排序没有变化。一定要提前创建一个Random对象复用。
  • 浅拷贝 vs 深拷贝:如果MobileObjects类里有引用类型的属性(比如position是自定义类的数组),Clone()只是浅拷贝,新数组和原数组会共享这些引用。如果需要完全独立的对象,你需要自己实现深拷贝方法(比如在MobileObjects里写一个Clone()方法,手动复制所有属性)。

内容的提问来源于stack exchange,提问作者Momo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:00:27