nBar
nBar

Reputation: 37

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

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"))

Upvotes: 0

Views: 70

Answers (2)

derpirscher
derpirscher

Reputation: 17372

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())

Upvotes: 0

DecPK
DecPK

Reputation: 25398

You can do this using split, map, and join as:

let str = "aHtuF"

const result = str
  .split("")
  .map((ch, i) => `${ch.toUpperCase()}${Array(i).fill(ch.toLowerCase()).join("")}`)
  .join("-")
console.log(result);

or

let str = "aHtuF"


const result = str
                .split("")
                .map((ch, i) => `${ch.toUpperCase()}${ch.toLowerCase().repeat(i)}`)
                .join("-")
                
console.log(result);

Upvotes: 1

Related Questions