-1

How can I grab a random line from a text file using Node.js?

What modifications do I need to make to my code?

const readline = require('readline');
const fs = require('fs');

var file = 'path.to.file';

var rl = readline.createInterface({
  input: fs.createReadStream(file),
  output: process.stdout,
  terminal: false
});

rl.on('line', function (line) {
  console.log(line) // print the content of the line on each linebreak
});
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135

1 Answers1

0

You could do worse than something like this. It: 0. Reads the file into memory as an array of lines

  1. Randomly shuffles the corpus
  2. Each call to next() returns the next line;
  3. When the corpus is exhausted, repeats from step #1 (shuffling)
const fs  = require('fs');

/**
 * 
 * @param {*} min 
 * @param {*} max 
 * @returns random integer n such that min <= n <= max
 */
 const randomInt = (min, max) => {
    const range = max - min + 1;
    const n = min + Math.floor( Math.random() * range );
    return n;
}

exports = module.exports = class RandomLines {
    constructor(pathToTextFile) {
        this.path  = pathToTextFile;
        this.n     = undefined;
        this.lines = undefined;
    }

    next() {
        if (!this.lines) {
            this.lines = fs.readFileSync('./some/path/to/a/file.txt').split( /\r\n?|\n/g );
            this.n     = this.lines.length;
            }
        if (this.n >= this.lines.length) {
            this.shuffleLines();
            this.n = 0;
        }
        return this.lines[n++]
    }

    init() {
    }

    /**
    * Shuffles the array lines
    */
    shuffleLines() {
        for (let i = this.lines.length - 1 ; i > 0 ; --i ) {
            const j = randomInt(0, i );
            const temp = this.lines[i];
            this.lines[i] = this.lines[j];
            this.lines[j] = this.lines[i];
        }
    }

}

Usage is pretty straightforward:

const RandomLines = require('./random-lines');
const randomLines = new RandomLines('./path/to/some/file.txt');

while (true) {
  console.log( randomLines.next() );
}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135