Search code examples
javascriptarraysstringnewlinemarkers

Remove Text, White Space That Follows Comment Marker in String With JavaScript - Create New Line In String


I'm trying to solve this CodeWars challenge:

Complete the solution so that it strips all text that follows any of a set of comment markers passed in. Any whitespace at the end of the line should also be stripped out.

Given an input string of:

apples, pears # and bananas
grapes
bananas !apples

The output expected would be:

apples, pears
grapes
bananas

So far I've tried:

function solution(input, markers) {
  
  let string = input.split();
  let newString = " ";

  for (let i = 0; i < string.length; i++) {
    
    let words = string[i];
    //console.log(words);

    if (words.includes(markers || "/n")) {
      //go to the next line and keep building newString
    }
    newString += words;
  }
  return newString.toString();
}

And this is returning apples,pears#andbananas/ngrapes/nbananas!apples because, as you can see, I don't know how to create a new line in the string when one of the markers is present, or when /n is present.

I've tried

if (words.includes(markers || "/n")) {
  //go to the next line and keep building newString
  newString += "\n";
}

and

if (words.includes(markers || "/n")) {
  //go to the next line and keep building newString
  words + "\n";
}

but neither of these are having any effect.


Solution

  • Sites that have coding challenges often have levels (like CodeWars). In this case I would suggest to stick a bit longer with the easier levels until you are really fluent in solving them.

    Also check the solutions that others have submitted: a lot can be learned from that.

    I say this because there are so many things wrong in your code, that it seems you will benefit more from covering easier levels a bit longer, than from just grabbing a solution here and posting it.

    Some comments on your code:

    • You initialise your newString with a space. That is a wrong start. That space is not warranted to be there. You should only take characters from the input. It should be an empty string.
    • The newline character is not "/n", but "\n"
    • input.split() converts a string to an array of characters. If your aim was to make it possible to access characters through indexing, then realise that you can do so with a string as well: input[i] gives you the character at that offset.
    • Variable names are important. Naming a variable string is not very helpful. Nor is words, when actually it holds one character. So character would be a better choice.
    • includes expects a string as argument, but you pass markers. The || "/n" has no additional value, because markers is a truthy value and so || will stop right there (short-circuit evaluation). And as markers is an array, not a string, includes converts that value into a comma-separated string. Obviously that string is very unlikely to occur in your input. You need to test for each marker character individually, and also check for the newline character.
    • The body of your if statement is empty (in your main attempt). This cannot be useful. Maybe you were looking for continue; which will skip the rest of the loop and continue with the next iteration of it.
    • There is no provision to skip the characters that follow a marker character.
    • You have no provision to eliminate spacing that occurs before a marker character.
    • newString is a string, so there is no need to call newString.toString();

    Trying to stay with your idea, here is your code corrected:

    function solution(input, markers) {
      let newString = "";
      for (let i = 0; i < input.length; i++) {
        let character = input[i];
        if (markers.includes(character)) {
            // move i to just before the end of the current line
            i = input.indexOf("\n", i)-1;
            // Remove the white space that we already added at the end
            newString = newString.trimRight();
            // If no newline character at end of last line: break
            if (i < 0) break;
            // Skip rest of this iteration
            continue;
        }
        newString += input[i];    
      }
      return newString;
    }
    

    But there are easier ways to do this. For instance, by splitting your input into lines first.

    Here is the solution I posted:

    const solution = (input, markers) =>
        input.split("\n").map(line => 
            markers.reduce((line, marker) => 
                line.split(marker, 1)[0].trimRight(), line)).join("\n");