1
\$\begingroup\$

I have the following code on my server that takes a string and inserts newlines in such a way that the string is separated into lines, all of which are shorter than maxLineLength in characters. This ensures that the text, when printed, will fit within a certain width.

const formatTextWrap = (text, maxLineLength) => {
  var words = text.replace(/[\r\n]+/g, ' ').split(' ')
  var lineLength = 0
  var output = ''
  for (var word of words) {
    if (lineLength + word.length >= maxLineLength) {
      output += `\n${word} `
      lineLength = word.length + 1
    } else {
      output += `${word} `
      lineLength += word.length + 1
    }
  }
  return output
}

What optimizations could I make? This code works, but are there any pitfalls to using this?

\$\endgroup\$
  • \$\begingroup\$ should this target console apps? If it's for a browser environment the css overflow properties would do just fine, I believe \$\endgroup\$ – Icepickle Aug 2 '17 at 10:45
  • \$\begingroup\$ Yes this is for console. Specifically for fixed width terminal \$\endgroup\$ – omgimanerd Aug 2 '17 at 17:37
4
\$\begingroup\$

I would modify a bit logic regarding spacing between words in lines. With your solution you might end up with unnecessary spaces on line ends.

Additionally using Array.reduce instead of for loop is more JS-way to join array.

const formatTextWrap = (text, maxLineLength) => {
  const words = text.replace(/[\r\n]+/g, ' ').split(' ');
  let lineLength = 0;
  
  // use functional reduce, instead of for loop 
  return words.reduce((result, word) => {
    if (lineLength + word.length >= maxLineLength) {
      lineLength = word.length;
      return result + `\n${word}`; // don't add spaces upfront
    } else {
      lineLength += word.length + (result ? 1 : 0);
      return result ? result + ` ${word}` : `${word}`; // add space only when needed
    }
  }, '');
}

let testingText = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam blandit mauris id venenatis tincidunt. Vestibulum at gravida sapien. Mauris tellus augue, aliquet sed laoreet blandit, pulvinar sed felis. Phasellus nec est vitae enim blandit facilisis.
Vestibulum fermentum ligula sit amet volutpat fermentum. Sed in faucibus orci. Pellentesque a dui ex. Curabitur sollicitudin, nulla id dignissim lacinia, odio mauris blandit nisi, eget auctor arcu odio nec est.`;
console.log(formatTextWrap(testingText, 20));

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This is fantastic, I hadn't thought of using Array.reduce. Thanks for the feedback. \$\endgroup\$ – omgimanerd Aug 2 '17 at 18:01
  • \$\begingroup\$ Glad to be helpful. \$\endgroup\$ – Miroslav Jonas Aug 3 '17 at 12:36
  • \$\begingroup\$ I would suggest .split(/\s+/) for the const words to allow multiple spaces to act as one split. This is for those warped individuals who wrongly believe their typing instructor from 1980 should govern how they space after punctuation in the 21st Century. \$\endgroup\$ – Alan Mimms Aug 10 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.