Search code examples
javascriptfor-loopuppercaselowercase

Jacascript: String puzzle with upper and lower case - one character not right


  • Input: aHtuE
  • Expected Output: A-Hh-Ttt-Uuuu-Eeeee
  • Actual Output: A-HH-Ttt-Uuuu-Eeeee

The function takes a string (in this example "aHtuE") and the output should be "A-Hh-Ttt-Uuuu-Eeeee". However the second "h" in this example appears in upper case instead of lower case. I guess it's a counting problem or so, but whatever I try, I don't get it.

function accum(s) {
  // Fill char with first character in upper case
  let char = (s.substring(0, 1)).toUpperCase();
  let result = "";

  for (i = 1; i <= s.length; i++) {
    // Add '-' 
    result += char + "-";
    // Get next char
    char = s.substring(i, i + 1)
    // For counting char
    for (j = 1; j <= i; j++) {
      // For putting each first new char in upper case
      if (j === 1) {
        char = char.toUpperCase();
        result += char;
      }
      // else lower case
      else {
        char = char.toLowerCase();
        result += char;
      }
    }
  }
  // Remove last '-' char and return result
  return result.substring(0, result.length - 1);
}

console.log(accum("aHtuE"))


Solution

  • When you enter the next iteration of the loop, you also add the previous char to your result. In case of the H this is still an uppercase H because for the H you never entered the branch where it was converted to lowercase because for the H the outer loops index i == 1 and thus, your j will not get > 1 ...

    The fix is easy: Add the correct number of the respective character within the same iteration of the outer loop ... See the //******** comments in the code for changes

    function accum(s) {
      let char = (s.substring(0, 1)).toUpperCase();
    
      //******************************
      //Initialize the result with the first character
      let result = char; 
    
      //*******************
      //don't need an extra loop iteration here
      for (i = 1; i < s.length; i++) {
    
        //***********************************
        // Add only '-' here instead of also the previous char 
        result += "-";
    
        char = s.substring(i, i + 1)
    
        //**********************************************************
        //Add the correct count of the current char to the result
        for (j = 0; j <= i; j++) {  
    
          //*****************
           //Of course need to adapt the condition here
          if (j === 0) {
            char = char.toUpperCase();
            result += char;
          }
          else {
            char = char.toLowerCase();
            result += char;
          }
        }
      }
      
      //**************************
      //no need to remove anything from result
      return result;
    }
    
    console.log(accum("aHtuE"))

    You can also simplify this code a bit as follows

    function accum(s) {
      //if s is an empty string or null or undefined 
      //just return an empty string as result
      if (!s) return "";
      let 
        //access character by index and make it uppercase immediately
        //initialize result with the first character
        result = s[0].toUpperCase(); 
        
      for (i = 1; i < s.length; i++) {
        //add the delimiter and current character as uppercase
        result += "-" + s[i].toUpperCase();
        //get the current character as lowercase
        let char = s[i].toLowerCase();
        //add the correct number of lowercase characters
        for (j = 0; j < i; j++) {  
          result += char;  
        }
      }
      return result;
    }
    
    console.log("aHtuE", accum("aHtuE"))
    console.log("foobar", accum("foobar"))
    console.log("empty string", accum(""))
    console.log("null", accum(null))
    console.log("undefined", accum(undefined))
    console.log("undefined", accum())