Skip to content

Instantly share code, notes, and snippets.

@maksimr
Last active September 23, 2024 09:43
Show Gist options
  • Save maksimr/de09e71af56db40d1172937ceaa0a86a to your computer and use it in GitHub Desktop.
Save maksimr/de09e71af56db40d1172937ceaa0a86a to your computer and use it in GitHub Desktop.
count lines in nodejs
//@ts-check
async function main() {
const assert = require('assert');
(/**@type {[number, string][]}*/([
[0, ''],
[1, ' '],
[1, '1'],
[1, '\n'],
[1, '\r'],
[1, '\r\n'],
[1, '1'],
[1, '1\n'],
[1, '1\r'],
[1, '1\r\n'],
[2, '\n\n'],
[2, '\r\r'],
[2, '\n\r'],
[2, '1\n2'],
[2, '1\n2\n'],
[2, '1\n '],
[4, '1\n2\r3\r\n4'],
])).forEach(async ([expected, text]) => {
assert.strictEqual(expected, countLinesSync(text));
assert.strictEqual(expected, await countLines(text));
});
/**
* @param {string} text
* @returns {Promise<number>}
*/
async function countLines(text) {
if (!text || text.length === 0) {
return 0;
}
const readline = require('node:readline');
const stream = require('node:stream');
const textStream = new stream.Readable();
textStream.push(text);
textStream.push(null);
const rl = readline.createInterface({
input: textStream
});
let count = 0;
for await (const _ of rl) {
count += 1;
}
rl.close();
textStream.destroy();
return count;
}
/**
* @param {string} text
* @returns {number}
*/
function countLinesSync(text) {
const LF = '\n';
const CR = '\r';
const textLengh = text?.length || 0;
let lineCount = 0;
let feedNewLine = true;
for (let i = 0; i < textLengh; i++) {
const char = text[i];
if (feedNewLine) {
lineCount++;
feedNewLine = false;
}
if (char === LF || char === CR) {
/*CRLF*/
if (char === CR && i < textLengh && text[i + 1] === LF)
i++;
feedNewLine = true;
}
}
return lineCount;
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment