【问题标题】:Randomize files output in folder随机化文件夹中的文件输出
【发布时间】:2025-12-25 18:40:11
【问题描述】:

我如何随机化我输出的文件的顺序:

string[] files = Directory.GetFiles("folder");

谢谢! :-)

【问题讨论】:

标签: c# asp.net random


【解决方案1】:

一种选择是使用Random

Random rng = new Random();

然后:

var randomOrderFiles = files.OrderBy(f => rng.Next());

这不是最有效的方法,因为它需要 O(nlogn)。如果这对您来说是个问题,那么存在更好的算法。

【讨论】:

    【解决方案2】:

    如果你不能使用 Linq,下面的方法应该可以工作:

    static Random rand = new Random();
    static void Randomize<T>(IList<T> list)
    {
        for (int i = list.Count - 1; i > 0; i--)
        {
            int i2 = rand.Next(i + 1);
            if (i2 != i)
            {
                T tmp = list[i2];
                list[i2] = list[i];
                list[i] = tmp;
            }
        }
    }
    

    【讨论】:

    【解决方案3】:

    A Fisher-Yates-Durstenfeld shuffle 是 O(n) 并且应该给出无偏分布。

    GetFiles返回的数组上为perform an in-place shuffle创建一个辅助/扩展方法:

    // uses ShuffleInPlace extension from https://*.com/a/5589250/55847
    var arrayOfFiles = Directory.GetFiles("folder");
    arrayOfFiles.ShuffleInPlace();
    

    如果您更喜欢返回一个新序列——就像 LINQ——你可以创建一个合适的 Shuffle extension method 来代替:

    // uses Shuffle extension from https://*.com/a/1653204/55847
    var sequenceOfFiles = Directory.EnumerateFiles("folder").Shuffle();
    

    【讨论】:

      【解决方案4】:
      1. 遍历源列表。
      2. 从源列表中删除随机源项
      3. 将已删除的项目附加到结果列表中
      4. 重复直到源列表为空

      List<string> files = Directory.GetFiles("folder");
      List<string> result = new List<string>();
      
      while (files.Count > 0)
      {
        int n = IntegerUtility.Random(files.Count);
        string file = files.Remove(n);
        result.Add(file);
      } 
      return result;
      

      【讨论】: