简体   繁体   中英

while loop is not working properly

I am writing code for my one of the exercises in freecodecamp.com called as Pig Latin problem. For a while loop it should stop executing the code inside it when the condition becomes wrong.For my case the while loop must stop executing the codes inside it when it finds that it seen a vowel in the charas array during iteration. I think my code is correct in my point of view, but while loop is not stopping execution when it sees a vowel instead it iterate through every element in the charas array.

Here is my code

function translatePigLatin(str) {
  var vowels = ['a','e','i','o','u'];
  var f="";
  var charas = str.split("");
  if(vowels.indexOf(charas[0])!==-1) {
      // vowel
    charas.push("w");
    charas.push("a");
    charas.push("y");
    f = charas.join("");
  } else {
    //if first letter  is a consonant or cluster of consonants
    var i = 0;
    while(vowels.indexOf(charas[i]) ===-1) {
     charas.push(charas[i]);
     charas.splice(i,1);
     i = i+1;
     }    
   charas.push('a');
   charas.push('y');
   f  = charas.join("");   
  }
  return f;
}

translatePigLatin("california");

It works as work cause

 charas.push(charas[i]);
 charas.splice(i,1);
 i = i+1;

After the first iteration it move 'a' letter at the begging as result i == 1 (in second iteration) charas[i] refers to consonant 'l'.

You haven't added the condition to exit the while loop, use i <= length of charas . Check below snippet.

 function translatePigLatin(str) { var vowels = ['a', 'e', 'i', 'o', 'u']; var f = ""; var charas = str.split(""); if (vowels.indexOf(charas[0]) !== -1) { // vowel charas.push("w", "a", "y"); f = charas.join(""); } else { //if first letter is a consonant or cluster of consonants var i = 0; var len = charas.length; while (vowels.indexOf(charas[i]) === -1 && i <= len) { charas.push(charas[i]); charas.splice(i, 1); i++; } charas.push('a', 'y'); f = charas.join(""); } return f; } console.log(translatePigLatin("california"));

The problem is that your are iterating AND modifying the same array at the same time

You can simplify your code like this

 function translatePigLatin(str) { var vowels = ['a', 'e', 'i', 'o', 'u']; //start with vowel if (vowels.indexOf(str[0]) !== -1) { return str + "way"; } var i = 0; var beforeVowel = ""; var chars = str.split(""); while (vowels.indexOf(chars[i]) === -1 && i < str.length) { beforeVowel += chars[i]; i++; } return str.substring(i) + beforeVowel + "ay"; } console.log(translatePigLatin("california")); console.log(translatePigLatin("pig")); console.log(translatePigLatin("eat"));

Your problem is that you increment i . You move the first element from the start of the array and then increment i you are skipping a letter because what was charas[1] is now charas[0] and what is charas[1] was charas[2] .

If you step through the code and inspect the charas array you can see this happening:

Starting state:

["c", "a", "l", "i", "f", "o", "r", "n", "i", "a"]

"c" gets moved to the end i is incremented to 1

["a", "l", "i", "f", "o", "r", "n", "i", "a", "c"]

"l" is at position 1 , so it gets moved to the end. i is incremented to 2

["a", "i", "f", "o", "r", "n", "i", "a", "c", "l"]

"f" is at position 2 , so it gets moved to the end. i is incremented to 3

["a", "i", "o", "r", "n", "i", "a", "c", "l", "f"]

"r" is at position 3 , so it gets moved to the end. i is incremented to 4

["a", "i", "o", "n", "i", "a", "c", "l", "f", "r"]

"i" is at position 4 , the while condition is met, "aioniaclfr" will be returned.

If you just get rid of i and always check charas[0] it works like expected:

 function translatePigLatin(str) { var vowels = ['a','e','i','o','u']; var f = ""; var charas = str.split(""); if(vowels.indexOf(charas[0]) !== -1) { // vowel charas.push("w"); charas.push("a"); charas.push("y"); f = charas.join(""); } else { //if first letter is a consonant or cluster of consonants while(vowels.indexOf(charas[0]) === -1) { charas.push(charas[0]); charas.splice(0,1); } charas.push('a'); charas.push('y'); f = charas.join(""); } return f; } document.getElementById('out').textContent = translatePigLatin("california");
 <div id="out"></div>

As a side note, this type of while condition will lead to an infinite loop if someone passes in a string that is all consonants, it will just keep shuffling the letters around because it will never find a vowel to stop it. To avoid this, I would add another if condition to check for that to make sure it won't happen:

 function translatePigLatin(str) { var vowels = ['a','e','i','o','u']; var f = ""; var charas = str.split(""); if (!str.match(/[aeiou]+/)) { // only consonants do something f = str + 'ay'; } else if (vowels.indexOf(charas[0]) !== -1) { // vowel charas.push("w"); charas.push("a"); charas.push("y"); f = charas.join(""); } else { //if first letter is a consonant or cluster of consonants while(vowels.indexOf(charas[0]) === -1) { charas.push(charas[0]); charas.splice(0,1); } charas.push('a'); charas.push('y'); f = charas.join(""); } return f; } document.getElementById('out').textContent = translatePigLatin("wkrp");
 <div id="out"></div>

/[aeiou]+/ is a regular expression meaning any vowel one or more times anywhere in the string the ! in !str.match(/[aeiou]+/) negates the result of match , so if there are no vowels in the string that branch of the if is followed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM