c# - 将文件中的 10 行(无重复)随机写入 15 个文件中的每一个

c# - write 10 random lines from a file (without duplicates) into each of 15 files

所以我一直在尝试制作一个功能

  1. 遍历包含 26 个文件的文件夹中的每个文件,
  2. 从 20 行的文件中随机抽取 10 行,
  3. 检查当前选择的行是否已经在当前文件中,如果是则再次尝试选择,
  4. 将 10 行随机写入每个文件。

这就是我目前所得到的。但是不知道为什么总是出界。我试过通过循环将文件中的行放入另一个数组,但这也无济于事。有没有人看出哪里出了问题?

string[] lines = File.ReadAllLines(@"randomLines.txt");
assignLines(lines);
static void assignLines(string[] listOfLines)
        { 
            Random rnd = new Random();

            foreach (var file in Directory.EnumerateFiles(@"files", @"*.txt"))
            {
                string[] assignedLines = new string[] { };
                int j = 1;
                int i = 0;
                StreamWriter wr = new StreamWriter(file);
                while (i < 5)
                //for (int i = 0; i < File.ReadAllLines(file).Length + 1; i++)
                {

                    int chosen = rnd.Next(0, listOfLines.Length - 1);

                    if (assignedLines.Contains(listOfLines[chosen]))
                    {
                        continue;
                    }
                    else
                    {
                        assignedLines[i] = listOfLines[chosen];
                        wr.WriteLine(j + ". " + listOfLines[chosen] + ".");
                        j++;
                        i++;
                    }
                }
                wr.Close();
            }
        }

您可以随机排列您的线条,然后取其中的 10 条,而不是每次都获取一条随机线条并循环遍历线条以查看它是否重复:

Random rnd = new Random();
string[] lines = File.ReadAllLines(@"randomLines.txt")
                 .OrderBy(x => rnd.Next())
                 Take(10)
                 .ToArray();

如果正如您在评论中提到的那样,您的行也可能包含重复项,请在订购前删除重复项:

string[] lines = File.ReadAllLines(@"randomLines.txt")
                 .Distinct()     //this line will remove duplicates
                 .OrderBy(x => rnd.Next())
                 Take(10)
                 .ToArray();

现在你可以循环思考文件并编写这 10 行。

如果我理解您的要求,理论上这应该对您有用

    string[] lines = File.ReadAllLines("FILE");
    
                // This will filter the array so that items which only appear once in 'lines' will be returned.
                // Once because lines will also contain the current item we are checking against.
                //Take 10 just returns the first 10 from that list
    string[] linesThatOnlyApprearOnce = lines.Where(x => lines.Count(y => x == y) == 1).Take(10).ToArray();