c#从txt文件中读取“n”个随机行数

问题描述:

我试图从文本文件中读取(n)大量的随机行,其中包含大约200个条目(行)并填充名为“recSongs”的列表框。我提供了一些简单的代码,它从文本文件中检索一个随机行,但我想要检索n个量。c#从txt文件中读取“n”个随机行数

这是我的代码。

var lines = File.ReadAllLines(@"file.txt"); 
var r = new Random(); 
var randomLineNumber = r.Next(0, lines.Length - 1); 
var line = lines[randomLineNumber]; 
recSongs.Items.Add(line); 
+0

最后一行永远不会被选中,由于第二个参数是不包括在内。 – dcg

+0

你需要避免两次同一行吗? – Tee

var lines = File.ReadAllLines(@"file.txt"); 
var r = new Random(); 

var randomized = lines.OrderBy(item => r.Next()); //randomize the list 
recSongs.Items.AddRange(randomized.Take(N).ToArray()); //Add N amount to listbox 

该解决方案还避免了重复的随机量

n将被输入,即无行的,你需要

List <string> text = File.ReadLines("file.txt").Take(n).ToList(); 

编辑

如果您需要随机的线条,你可以做,

 string[] lines = File.ReadAllLines(@"C:\YourFile.txt"); 
     List<string> source = new List<string>(); 
     int n = 10; 
     for (int i = 0; i < n; i++) 
     { 
      source.Add(lines[new Random().Next(lines.Length)]); 
     } 
+1

他想得到'n'个随机线。你在做第一个'n'行。 – dcg

+0

@dcg是更正 – Sajeetharan

+0

使用一个随机实例(而不是每次在该时钟播种的时候新建一个实例)可能会提供更好的随机性。 – slimbofat

这将添加numLines随机线到您的收藏。请注意,有可能会有重复。

var lines = File.ReadAllLines(@"file.txt"); 
var r = new Random(); 
int numLines = 5; 

for (int i = 0; i < numLines; i++) 
{ 
    recSongs.Items.Add(lines[r.Next(0, lines.Length - 1)]); 
} 

强制使用唯一的项目,你可以做这样的事情:

for (int i = 0; i < numLines; i++) 
{ 
    var randomItem = string.Empty; 

    do 
    { 
     randomItem = lines[r.Next(0, lines.Length - 1)]; 

    } while (recSongs.Contains(randomItem)); 

    recSongs.Items.Add(randomItem); 
} 

但现在请注意,这是可能的,它永远不会退出。随机的欢乐!

+0

原则上,您多次添加同一条线。 – dcg

+0

是的,当您输入评论时,我正在更新答案!但是'OrderBy(x => Guid.NewGuid())。拿(n)'答案是最好的 –

+0

我同意你的观点,那个答案应该被接受。 – dcg

也许最简单的方法,虽然不是最记忆效率,是把文件啜到内存中集合了线,然后Shuffle()线,并采取然而,许多你想要的:

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> input) 
    { 
     var buffer = input.ToArray(); 
     //Math.Random is OK for "everyday" randomness; 
     //use RNGCryptoServiceProvider if you need 
     //cryptographically-strong randomness 
     var rand = new Random(); 

     //As the loop proceeds, the element to output will be randomly chosen 
     //from the elements at index i or above, which will then be swapped 
     //with i to get it out of the way; the yield return gives us each 
     //shuffled value as it is chosen, and allows the shuffling to be lazy. 
     for (int i = 0; i < buffer.Length; i++) 
     { 
      int j = rand.Next(i, buffer.Length); 
      yield return buffer[j]; 
      //if we cared about the elements in the buffer this would be a swap, 
      //but we don't, so...  
      buffer[j] = buffer[i]; 
     } 
    } 

    ... 

    string[] fileLines = GetLinesFromFile(fileName); //a StreamReader makes this pretty easy 
    var randomLines = fileLines.Shuffle().Take(n); 

一些注意事项:

  • 这应该适用于约200行的文本文件;超过几十万行,你会开始有内存问题。一个更具可扩展性的解决方案是洗牌一系列的行号,然后使用它们来寻找并阅读你想要的特定行,并丢弃所有其他行。
  • 该解决方案以随机顺序生成随机线。如果要保留文件中行的顺序,请执行行号变体,对选择的行号进行排序,然后在将它们从文件中读出后按顺序保持行。

试试这个

var lines = File.ReadAllLines(@"file.txt"); 
var r = new Random(); 
int noLines = 10;// n lines 

for (int i = 0; i < noLines; i++) 
{ 
    var randomLineNumber = r.Next(0, lines.Length - 1); 
    var line = lines[randomLineNumber]; 
    recSongs.Items.Add(line); 
} 

你可以这样做:

HashSet<int> linesHash = new HashSet<int>(); 
var lines = file.ReadLines(); 
for (int i = 0; i < numLinesToGet; i++) 
{ 
    int line=0; 
    do 
    { 
     line = rand.Next(0, lines.Length); 
    }while(linesHash.Contains(line)); 
    linesHash.Add(line); 
    linesAdded.Add(lines[line]); 
} 

注意,如果线得到量小于实际的行数大于我的代码永远不会结束,因此在执行for循环之前必须执行一些检查。

如何:

var lines = File.ReadAllLines("file.txt").OrderBy(x => Guid.NewGuid()).Take(n);

+0

太聪明了!我正在记录这种选择随机事物的方式。 –

+0

太棒了!但是这是如何工作的 – Sajeetharan

+0

@Sajeetharan每次调用'Guid.NewGuid()'都会生成一个新的'全局唯一标识符',所以这个集合随机地被这些值排序。然后从那里取第一个'n'元素。非常优雅的答案BTW。 – dcg

var lines = File.ReadAllLines(@"file.txt"); 
var random = new Random(); 

var lines = Enumerable.Repeat(-1, n) // -1 is a filler and is discarded by the select. 
.Select(_ => random.Next(0, lines.Length - 1)) 
.Select(index => lines[index]); 

foreach(var line in lines) 
{ 
    recSongs.Items.Add(line); 
}