2017-04-11 111 views
1

我試圖從文本文件中讀取(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

回答

0
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 

該解決方案還避免了重複的隨機量

1

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

0

這將添加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

0

也許最簡單的方法,雖然不是最記憶效率,是把文件啜到內存中集合了線,然後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行的文本文件;超過幾十萬行,你會開始有內存問題。一個更具可擴展性的解決方案是洗牌一系列的行號,然後使用它們來尋找並閱讀你想要的特定行,並丟棄所有其他行。
  • 該解決方案以隨機順序生成隨機線。如果要保留文件中行的順序,請執行行號變體,對選擇的行號進行排序,然後在將它們從文件中讀出後按順序保持行。
0

試試這個

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); 
} 
0

你可以這樣做:

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循環之前必須執行一些檢查。

4

如何:

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

+0

太聰明瞭!我正在記錄這種選擇隨機事物的方式。 –

+0

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

+0

@Sajeetharan每次調用'Guid.NewGuid()'都會生成一個新的'全局唯一標識符',所以這個集合隨機地被這些值排序。然後從那裏取第一個'n'元素。非常優雅的答案BTW。 – dcg

0
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); 
}