简体   繁体   中英

c# Read 'n' amount of random lines from txt file

I am attempting to read (n) amount of random lines from a text file with about 200 entries (lines) and populate a listbox called "recSongs". I have provided some simple code which retrieves one random line from the text file, but I want retrieve n amount.

Here is my code.

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

怎么样:

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

n will be the input , ie no of lines you need

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

Edit

If you need random lines, you could do,

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

This will add numLines random lines to your collection. Note that there is a chance that there will be duplicates.

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

To enforce unique items, you could do something like this:

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

But now note that it is possible that it will never exit. The joys of Random!

Probably the easiest way, though not the most memory-efficient, is to slurp the file into an in-memory collection of its lines, then Shuffle() the lines and take however many you want:

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

Some notes:

  • This should work fairly well for a text file of about 200 lines; beyond a couple hundred thousand lines, you'll start having memory problems. A more scalable solution would be to shuffle an array of line numbers, then use those to seek for and read the specific lines you want, discarding all the others.
  • This solution produces the random lines in random order. If you want to preserve the order of the lines from the file, do the line-number variant, sorting the line numbers you select, then just keep the lines in that order after reading them out of the file.

Try this

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

You could do something like:

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

Note that if the amount of lines to get is greater than the actually number of lines my code would never end, so some checks must be done prior to execute the for loop.

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

This solution also avoids duplicate randoms

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM