Reputation: 3
Basically I want to display vowels and consonants from string but I quite don't understand why my code below doesn't work properly.
const word = "javascriptloops";
let array = word.split("");
for (let i = 0; i < array.length; i++) {
if (
array[i] === "a" ||
array[i] === "e" ||
array[i] === "i" ||
array[i] === "o" ||
array[i] === "u"
) {
console.log(array[i]);
array.splice(i, 1);
}
}
for (let item of array) {
console.log(item);
}
The result it shows is: The result
Can someone explain what's the reason why it doesn't include this second "o" with the vowels?
Upvotes: 0
Views: 189
Reputation: 25408
AKX explained it beautifully. So this is just an alternative if you want vowels
and consonants
individually.
const word = "javascriptloops";
let vowel = word.match(/[aeiou]/g);
let consonants = word.match(/[^aeiou]/g);
console.log(vowel);
console.log(consonants);
If you want result in one loop then you could do something like
const word = "javascriptloops",
vowel = [],
consonants = [];
for (let char of word) {
if (char.match(/[aeiou]/)) vowel.push(char);
else consonants.push(char);
}
console.log(vowel);
console.log(consonants);
Upvotes: 0
Reputation: 169051
Since you're modifying the same array you're iterating over, you'll need to "skip back" one cell after removing an item.
That is, add i--;
after array.splice(i, 1);
To visualize this, you can try
console.log(array.join(""), array.length);
console.log(" ".repeat(i) + "^", i);
in your loop.
Without this skipping back, the output is
javascriptloops 15
^ 1
jvascriptloops 14
^ 2
jvscriptloops 13
^ 5
jvscrptloops 12
^ 8
With the fix, it's
javascriptloops 15
^ 1
jvascriptloops 14
^ 2
jvscriptloops 13
^ 5
jvscrptloops 12
^ 8
jvscrptlops 11
^ 8
This is made even more obvious with a string with more subsequent vowels, say, daemonium
:
No fix:
daemonium 9
^ 1
demonium 8
^ 3
demnium 7
^ 4
With fix:
daemonium 9
^ 1
demonium 8
^ 1
dmonium 7
^ 2
dmnium 6
^ 3
dmnum 5
^ 3
Upvotes: 1