Reputation: 4236
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");
Upvotes: 1
Views: 119
Reputation: 12402
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.
Upvotes: 0
Reputation: 13943
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"));
Upvotes: 0
Reputation: 9561
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"));
Upvotes: 0
Reputation: 261
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'.
Upvotes: 1