2

Edit: Since people seem a little confused, I will try to clarify.

Essentially, the string you take is a variable character length and can be any number of lines.

The hitch is the string has to not cutoff a word. So, as another example, the string:

'The jumping fox' is divided into 2 separate lines. The middle character is 'u', so the two lines would be: Line 1: 'The jumping' Line 2: 'Fox' to prevent the word being cutoff. So that is the two restrictions.

So, I got this question:

Given a single-line text String and a maximum line value, write the function that formats the input text , i.e: Divide the text evenly based on character, and return a new line for each section of the string. But do not cut off a line -- ie, if you have 1000 character, and 2 lines, you can increase the size of the first line to capture the end of the last word in the middle of the 500th character.

I am bashing my head trying to solve it in JavaScript. Any tips? It's easy enough to just return the lines without this whitespace formatting, but I am totally lost.

function formatString(string, numlines) {
  var length = string.length;
  console.log(length);
  var words = string.split(' ');
  var paraLength = parseInt(string.length/numlines);
  console.log(paraLength)

  var paragraph = [];  
  for(var i=0; i<length;) {
    // console.log('i is: ', i);
    console.log('start of string is: ', string.charAt(i));
    console.log('end of string is: ', string.charAt(i+paraLength+1));
    console.log('if true? ', string.indexOf(i) )
    if (string.charAt(i+paraLength) == ' ') {
      var thing = string.substr(i,i+paraLength);
      console.log('if thing is: ', thing);
      i+=paraLength;
      console.log('if i is: ', i);
      paragraph.push(thing);
    } else {
      var thing = string.substr(i,i+paraLength);
      console.log('else thing is: ', thing);
      console.log('blah is: ',i+paraLength+1 >= length);
      while (string.charAt(i+paraLength) != ' ' && i+paraLength < length) {
        thing.concat(string.charAt(i+paraLength+1));
        thing.concat('hi')
        console.log('else thing is: ', thing);
        i+=1;
        console.log('i is: ', i);
      }
      paragraph.push(thing);
      i+= paraLength;
    }
  }

  return paragraph.map(function(d) {
    console.log('d is: ', d);
    return d;
  }).join('')

}
console.log(formatString('hello world blah blah blah', 2));
5
  • You need the power of string.slice(). Commented Apr 2, 2016 at 2:37
  • Is there a hard limit on the length of any particular line so long as there are at most n lines? Commented Apr 2, 2016 at 2:43
  • No hard limit. It just can just vary due to what is contained in the string Commented Apr 2, 2016 at 3:34
  • this is still vague to me, I was playing around and I think I have it, what exactly would be the log for 'hello world blah blah blah', 2 ? Commented Apr 2, 2016 at 4:00
  • I think it should be with that string... Line 1: hello world blah, line 2: blah blah Commented Apr 2, 2016 at 4:08

2 Answers 2

2

If I'm understanding you're question, this might help:

function formatString(string, numlines) {
    var length = string.length;
    var paraLength = Math.round((string.length)/numlines);
    var paragraphs = [];
    for (var i=0; i<numlines; i++) {
        var marker = paraLength;
        //if the marker is right after a space, move marker back one character
        if (string.charAt(marker-1) == " ") {
            marker--; 
        }
        //move marker to end of a word if it's in the middle
        while(string.charAt(marker) != " " && string.charAt(marker) != "") {
            marker++;
        }
        var nextPara = string.substring(0, marker)
        paragraphs.push(nextPara)
        string = string.substring((nextPara.length+1),string.length)
    }
    return paragraphs
}

This returns an array that contains the individual paragraphs.

formatString("The jumping fox", 2) // => ["The jumping", "fox"]
Sign up to request clarification or add additional context in comments.

Comments

2

The proposed algorithm "you can increase the size of the first line to capture the end of the last word in the middle of the 500th character" has a fatal flaw: if your last word is longer than length(sentence)/num_lines and so you skip to 'the next word', you print out too many words in that line and end up with too little words – probably none at all – in the last line.

This can be solved by not considering a string as a sequence of characters (where you need to inspect each character to see if it is a space) but rather as a sequence of words. Then, the algorithm is that on each line num_words/num_lines must appear. Use Math.ceil to round up, so you are sure that on every line at least one word appears.

With that, you can create a basic test case to split up a list of words exactly in 2. The splitting itself could be done using the split function, but I prefer a regex match, so all spaces are preserved. match returns an array of matches, each of which are a single word plus its following whitespace. Since it's an array, you can divide its length by the number of lines, round up if it's a fraction (Math.ceil), then print out those words.

Next? Well, after that step you end up with a not-yet processed remainder of your original string and with a number of lines remaining. So you can call this same function again with the truncated string and one less number of lines. You are done when the number of lines is 1 (then the entire remaining string can be printed) and/or the number of spaces is 0 (not tested for here; I suppose you could first see if you have at least as many spaces-minus-1 as you have lines, and if not, issue an error).

console.log(formatString('hello world blah blah blah', 2));

function formatString (string, numLines)
{
    var wordlist, trim_at, result;
    if (numLines < 2)
        return string;

    wordlist = string.match(/\S+\s*/g);
    trim_at = Math.ceil(wordlist.length/numLines);

    result = '';
    while (trim_at--)
        result += wordlist.shift();
    result += '\n';
    result += formatString (wordlist.join(''), numLines-1);
    return result;
}

2 Comments

But by splitting it up by words something like "superlongword a a a a a a" gets split up into the lines "superlongword a a a" and "a a a" instead of "superlongword" and "a a a a a a"
I get what you're going for -- essentially, as numlines gets large and the string gets large, the chance the last lines will be truncated is pretty high. I imagine the secret is probably going backwards and forward to the NEAREST whitespace, not the whitespace the end like I think you were getting at.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.