Results 1 to 11 of 11

Thread: Best way to read a random line from a text file ?

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Best way to read a random line from a text file ?

    I read all, and then picked a random number. Is there a better way? How would you do it?

    Code:
        Public Function getRandomWord2() As String
    
            Dim objStreamReader As StreamReader
            Const FILENAME As String = "C:\words.txt"
            Dim line As String
            Dim allWords As New List(Of String)
            Dim generator As New Random
            Dim n As Integer
    
            objStreamReader = New StreamReader(FILENAME)
    
            line = objStreamReader.ReadLine
            Do While (Not line Is Nothing)
                allWords.Add(line)
                Console.WriteLine(line)
                line = objStreamReader.ReadLine
            Loop
            objStreamReader.Close()
    
            n = generator.Next(1, allWords.Count)
    
            Return allWords(n)
    
        End Function

  2. #2

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Best way to read a random line from a text file ?

    Also, is it bad practice to access a list element using an index? like an array.
    Is order not guaranteed in a list? What would be the right way to do this above?

  3. #3
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Best way to read a random line from a text file ?

    If the length of text on each line can be different, you do basically need to read the whole file (and store the data, at least temporarily), so your method is certainly valid.

    Quote Originally Posted by RipVoidWinkle View Post
    Also, is it bad practice to access a list element using an index? like an array.
    Is order not guaranteed in a list? What would be the right way to do this above?
    A List is a glorified version of an array, so it is perfectly valid to read items using an index.

    The order of items is maintained (like in an array), so the way you have done it is correct.

  4. #4
    Fanatic Member Delaney's Avatar
    Join Date
    Nov 2019
    Location
    Paris, France
    Posts
    845

    Re: Best way to read a random line from a text file ?

    you should also put

    Code:
    Dim generator As New Random
    outside the function.
    The best friend of any programmer is a search engine
    "Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
    “They did not know it was impossible so they did it” (Mark Twain)

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Best way to read a random line from a text file ?

    Unless the file is so large that reading the whole thing took noticeable time, I would definitely read all the lines in, though I think I'd use ReadAllLines to put the whole thing into an array. For your purposes, the way you did it might be superior...with one exception...perhaps: You pick a random number from 1 to Count. That will work, since the end value is not included, but by doing that, you guarantee that you will never get the first member as a random selection. Is that what you want?
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Best way to read a random line from a text file ?

    Quote Originally Posted by Delaney View Post
    you should also put

    Code:
    Dim generator As New Random
    outside the function.
    Even if I only call the function once ?

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Best way to read a random line from a text file ?

    Quote Originally Posted by Shaggy Hiker View Post
    You pick a random number from 1 to Count. That will work, since the end value is not included, but by doing that, you guarantee that you will never get the first member as a random selection. Is that what you want?
    Right, so
    n = generator.Next(0, allWords.Count)

    Wow, for once that MAX+1 glitch actually comes in handy, and I don't need to add +1
    Maybe this is why it's like that .

  8. #8
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Best way to read a random line from a text file ?

    Quote Originally Posted by RipVoidWinkle View Post
    Even if I only call the function once ?
    If you only call it once in total then it doesn't matter.

    If you might ever call it more than once while the program is running, then Delaney's suggestion is better (and the other is dodgy).


    In either case Delaney's suggestion is fine, so it is better to use it anyway - it covers you if you have a change of usage later.

  9. #9
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Best way to read a random line from a text file ?

    The issue with Random is that when you create the Random object, you seed it. The seed is the system time. If you create new Random objects in a loop, then you might create more than one with the same seed. Two random number generators with the same seed will produce identical results. If you can be CERTAIN that there can't be two created within the same second (it may be even finer scale than that), then you could produce multiple Random objects safely. It would waste a bit of space, but only a bit. However, screw that up once and your randomness is gone, which tends to cause trouble. Creating just one for a program is not just more efficient, it means that you don't have to worry about your randomness.
    My usual boring signature: Nothing

  10. #10
    Fanatic Member Delaney's Avatar
    Join Date
    Nov 2019
    Location
    Paris, France
    Posts
    845

    Re: Best way to read a random line from a text file ?

    Quote Originally Posted by Shaggy Hiker View Post
    The seed is the system time. If you create new Random objects in a loop, then you might create more than one with the same seed. Two random number generators with the same seed will produce identical results.
    Yep, I just experienced that a few days ago. Took me sometimes until I understand that my loop took only 8ms which was less that the 15ms recommended by the documentation...
    Last edited by Delaney; Jan 4th, 2021 at 07:08 PM.
    The best friend of any programmer is a search engine
    "Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
    “They did not know it was impossible so they did it” (Mark Twain)

  11. #11
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Best way to read a random line from a text file ?

    If you know how many lines the file contains and you only want one of them, this is the best way to get a random line:
    vb.net Code:
    1. Private rng As New Random
    2. Private lineCount As Integer
    3. Private filePath As String
    4.  
    5. Private Function GetRandomLine() As String
    6.     Dim index = rng.Next(lineCount)
    7.  
    8.     Return File.ReadAllLines(filePath).Skip(index).First()
    9. End Function
    If you don't know how many lines there are or you want more than one, this is the best way:
    vb.net Code:
    1. Private rng As New Random
    2. Private filePath As String
    3. Private lines As String()
    4.  
    5. Private Function GetRandomLine() As String
    6.     If lines Is Nothing Then
    7.         lines = File.ReadAllLines(filePath)
    8.     End If
    9.  
    10.     Dim index = rng.Next(lines.Length)
    11.  
    12.     Return lines(index)
    13. End Function
    Note the use of ReadLines the first time and ReadAllLines the second time. The first one reads one line at a time, stops at the line of interest and discards the others. The second one reads all lines into an array that is kept for reuse.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width