diff --git a/index.js b/index.js index d02f7f7..d942eee 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,35 @@ export default function trimNewlines(string) { - return string.replace(/^[\r\n]+|[\r\n]+$/g, ''); + let start = 0; + let end = string.length; + + while (start < end && (string[start] === '\r' || string[start] === '\n')) { + start++; + } + + while (end > 0 && (string[end - 1] === '\r' || string[end - 1] === '\n')) { + end--; + } + + return (start > 0 || end < string.length) ? string.slice(start, end) : string; } -trimNewlines.start = string => string.replace(/^[\r\n]+/, ''); -trimNewlines.end = string => string.replace(/[\r\n]+$/, ''); +trimNewlines.start = string => { + const end = string.length; + let start = 0; + + while (start < end && (string[start] === '\r' || string[start] === '\n')) { + start++; + } + + return start > 0 ? string.slice(start, end) : string; +}; + +trimNewlines.end = string => { + let end = string.length; + + while (end > 0 && (string[end - 1] === '\r' || string[end - 1] === '\n')) { + end--; + } + + return end < string.length ? string.slice(0, end) : string; +}; diff --git a/test.js b/test.js index e677076..1879959 100644 --- a/test.js +++ b/test.js @@ -2,6 +2,9 @@ import test from 'ava'; import trimNewlines from './index.js'; test('main', t => { + t.is(trimNewlines(''), ''); + t.is(trimNewlines(' '), ' '); + t.is(trimNewlines('\n\n\r'), ''); t.is(trimNewlines('\nx\n'), 'x'); t.is(trimNewlines('\n\n\nx\n\n\n'), 'x'); t.is(trimNewlines('\r\nx\r\n'), 'x'); @@ -9,6 +12,9 @@ test('main', t => { }); test('start', t => { + t.is(trimNewlines.start(''), ''); + t.is(trimNewlines.start(' '), ' '); + t.is(trimNewlines.start('\n\n\r'), ''); t.is(trimNewlines.start('\nx'), 'x'); t.is(trimNewlines.start('\r\nx'), 'x'); t.is(trimNewlines.start('\n\n\n\nx'), 'x'); @@ -17,9 +23,42 @@ test('start', t => { }); test('end', t => { + t.is(trimNewlines.end(''), ''); + t.is(trimNewlines.end(' '), ' '); + t.is(trimNewlines.end('\n\n\r'), ''); t.is(trimNewlines.end('x\n'), 'x'); t.is(trimNewlines.end('x\r\n'), 'x'); t.is(trimNewlines.end('x\n\n\n\n'), 'x'); t.is(trimNewlines.end('x\n\n\r\n\n'), 'x'); t.is(trimNewlines.end('\n\n\r\n\nx'), '\n\n\r\n\nx'); }); + +test('main - does not have exponential performance', t => { + for (let index = 0; index < 45000; index += 1000) { + const string = String(Array.from({length: index}).fill('\n').join('')) + 'a' + String(Array.from({length: index}).fill('\n').join('')); + const start = Date.now(); + trimNewlines(string); + const difference = Date.now() - start; + t.true(difference < 10, `Execution time: ${difference}`); + } +}); + +test('start - does not have exponential performance', t => { + for (let index = 0; index < 45000; index += 1000) { + const string = String(Array.from({length: index}).fill('\n').join('')) + 'a'; + const start = Date.now(); + trimNewlines.start(string); + const difference = Date.now() - start; + t.true(difference < 10, `Execution time: ${difference}`); + } +}); + +test('end - does not have exponential performance', t => { + for (let index = 0; index < 45000; index += 1000) { + const string = 'a' + String(Array.from({length: index}).fill('\n').join('')); + const start = Date.now(); + trimNewlines.end(string); + const difference = Date.now() - start; + t.true(difference < 10, `Execution time: ${difference}`); + } +});