0

Working on a CoderByte problem and the first for loop isn't executing on the first or last loop. The function is to convert every letter to the next one after it in the alphabet, then switch all vowels to uppercase. For example input "coderbyte" is returning "fpdfsczUE" when it should be "dpdfsczUf". All variables and tests seem to be functioning (see comments). Any help would be appreciated - they give the answers but won't explain why this won't work.

function LetterChanges(str) {
    // convert every letter in a string to the letter after in the alphabet, 
    // then convert all vowels to uppercase, and return the string.

      var alpha = "abcdefghijklmnopqrstuvwxyz";
      var vowels = "aeiou";

      for (var i=0; i<str.length; i++) {
        // return (alpha.indexOf(str[i]) !== -1); checks true on first loop
        if (alpha.indexOf(str[i]) !== -1) {
          //return alpha[alpha.indexOf(str[i]) + 1]; // returns d correctly
          // return alpha.indexOf(str[i]) + 1; // returns 3 correctly

          //return str[i]; returns "c" correctly
          // return str.replace(str[i], "X"); returns Xoderbyte correctly
          // return str.replace(str[i+1], alpha[alpha.indexOf(str[i]) + 1]); 
          //returns cdderbyte correctly
          //    BUG: why isn't the line below working on the first and last   
             //     loop ?
             //  ie. input "coderbyte" returns "fpdfsczUE"
            str = str.replace(str[i], alpha[alpha.indexOf(str[i]) + 1]);
        }

      }
      //return alpha[alpha.indexOf(str[i])];



      for (var j=0; j<str.length; j++) {
        if (vowels.indexOf(str[j]) !== -1) {
            str = str.replace(str[j], str[j].toUpperCase());
        }
      }
      return str; 

    }
David Rhodes
  • 85
  • 1
  • 7
  • 4
    Do you know how to use a debugger (not all these `retutn` statements - a real debugger)? – Amit Jan 23 '16 at 01:54
  • 1
    Think about what happens if characters are repeated? For example, after the 1st iteration the string is "doderbyte". What happens in the third iteration? Does it replace the 3rd "d" (expected) or the 1st "d"? – Satyajit Jan 23 '16 at 02:29
  • http://ericlippert.com/2014/03/05/how-to-debug-small-programs/ –  Jan 23 '16 at 04:48
  • Thanks Satyajit. Amit, no - prepping for a fullstack bootcamp and the work hasn't covered that yet. – David Rhodes Jan 23 '16 at 18:53

2 Answers2

0

Your question output is not proper "coderbyte" needs to change to "dpEfsczUf" not "dpdfsczUf".

We need to replace character at particular index as str.replace will replace first occurrence only.

replaceAt function can help

So modified code below can work

String.prototype.replaceAt=function(index, character) {
    return this.substr(0, index) + character + this.substr(index+character.length);
}

function LetterChanges(str) {
    // convert every letter in a string to the letter after in the alphabet,
    // then convert all vowels to uppercase, and return the string.

      var alpha = "abcdefghijklmnopqrstuvwxyz";
      var vowels = "aeiou";

      for (var i=0; i<str.length; i++) {
        if (alpha.indexOf(str[i]) !== -1) {
            str = str.replaceAt(i, alpha[alpha.indexOf(str[i]) + 1]);
        }

      }
      for (var j=0; j<str.length; j++) {
        if (vowels.indexOf(str[j]) !== -1) {
            str = str.replaceAt(j, str[j].toUpperCase());
        }
      }
      return str; 

    }
Community
  • 1
  • 1
Jagdish Idhate
  • 7,513
  • 9
  • 35
  • 51
0

You're misunderstanding how .replace() works. (see Satyajit's comment on your question) This is why the second part of your function works flawlessly; once a vowel has been converted to upper case, it can't be the basis of another character's transformation.

Regarding the first loop: if a letter in a pass after the first one matches a letter closest to i=0, then that letter will be the one that's replaced, not the one you intended.

If you use a debugger or even add a console.log(str) after the first loop's assignment, it will be evident what's going on.

zahabba
  • 2,921
  • 5
  • 20
  • 33