Intermediate Algorithm Scripting: Pig Latin - handling words without vowels

Tell us what’s happening:

Hello. I need some help with this test. I can’t pass it, it says “Should handle words without vowels”. I think the information is not enough to figure out this error.

Thanks for the help!

This is the Intermediate Algorithm Scripting: Pig Latin

Translate the provided string to pig latin.

Pig Latin takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an “ay”.

If a word begins with a vowel you just add “way” to the end.

Input strings are guaranteed to be English words in all lowercase.

Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code.

Your code so far


function translatePigLatin(str) {
  if("aeiou".indexOf(str[0]) === -1  ) {
    return str.replace(/(^[b-df-hj-np-tv-z]*)(\w+)/, "$2$1ay" );
  } else {
    return str.concat("way");
    } 
}
translatePigLatin("consonant");

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/pig-latin

The test Should handle words without vowels. means that your code should work when you get words without vowels. I quickly did a test with your code and if I would take the non existent word: pkljdsk, in pig latin this would be pkljdskay but if I use your code, I get kpkljdsay. Your first letter is wrong.

Edit: This is because they say consonant or consonant cluster, so your full word is one cluster and moves to the back => stays the same. Currently one letter is moved.

2 Likes

Thanks, I already fix it.

function translatePigLatin(str) {
if(!str.match(/[aeiou]/)) {
return str.concat(“ay”);
} else if(“aeiou”.indexOf(str[0]) === -1 ) {
return str.replace(/(^[b-df-hj-np-tv-z]*)(\w+)/, “$2$1ay” );
} else {
return str.concat(“way”);
}
}

translatePigLatin(“consonant”);

It’s messy. I should clean it.

Thanks

1 Like
function translatePigLatin(str) {
  let j = 0;  // counter for words starting with vowel
  const unmodifiedStr = str;
  for (let i = 0; i < str.length; i++) {
    if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
      if (j === 0) {
        return str + "way";
      } else {
        return str + "ay";
      }
      } else {
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;
      j = 1;
    }
  }
  return unmodifiedStr;
}

I couldn’t pass the test: “Should handle words without vowels.”

This is not an endless loop. my outputs were correct running the tests (functions with parameters) in a jsbin online editor. it’s just that i couldn’t pass the “Should handle words without vowels.” test.

      console.log(str);
      console.log(i);
      str = str.slice(i+1,str.length) + str.slice(0,1);
      console.log(str);
      console.log(i);
      i--;
      console.log(i);
translatePigLatin("california");

output:
“california”
0
“aliforniac”
0
-1

Reason: i needed the var i to be -1 so that when it loops back, var i becomes 0 and evaluates the first “a” of “aliforniac”.

If var i stayed 0 (and when it loops it becomes 1), the “l” will be evaluated in “aliforniac” missing out “a”.

Here’s a better indentation

function translatePigLatin(str) {
  let j = 0;  // counter for words starting with vowel
  const unmodifiedStr = str;
  for (let i = 0; i < str.length; i++) {
    if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
      
      // starts with a vowel (without modifying string)
      if (j === 0) {
        return str + "way";
     
     // if first index is a vowel (after modifying string)
      } else {
        return str + "ay";
      }
      
    // if letter is consonant at index 0.
    } else {
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;  // return to index 0 until reaching end of str.length
      j = 1;    // to disallow evaluation of first conditional (j === 0) the second time around.
    }
  }
 
 // exit loop, return if no vowels were found.
  return unmodifiedStr;
}


translatePigLatin("rhythm");

Thanks for looking into this.

Here. I removed the str.length. It’s still not passing the last test.

function translatePigLatin(str) {
  let j = 0;  // counter for words starting with vowel
  const unmodifiedStr = str;
  for (let i = 0; i <= 1; i++) {
    if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
      
      // starts with a vowel (without modifying string)
      if (j === 0) {
        return str + "way";
     
     // if first index is a vowel (after modifying string)
      } else {
        return str + "ay";
      }
      
    // if letter is consonant at index 0.
    } else {
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;  // return to index 0 until reaching end of str.length
      j = 1;    // to disallow evaluation of first conditional (j === 0) the second time around.
    }
  }
 
 // exit loop, return if no vowels were found.
  return unmodifiedStr;
}


translatePigLatin("rhythm");

Hi, can you please explain your regex for the replace function?
Thank you

function translatePigLatin(str) {
  if("aeiou".indexOf(str[0]) > -1){
    return str + "way";
  }else if( str.search(/[aeiou]/) > 0){
    return str.slice(str.search(/[aeiou]/), str.length) + str.slice(0, str.search(/[aeiou]/)) + "ay";
  }else{
    return str + "ay";
  }
}

Hope it helps.

2 Likes

my solve:
did not know how to blurr it out, so I hid the solution in the details tag. :wink:

Summary
function translatePigLatin(str) {
  let myStr = "";
  if (str.match(/^([aeoui])/i) !== null) {
  	myStr = str + 'way';
  }
  else {
  	myStr = str.replace(/([^aeoui]*)(.*)/i, '$2$1');
  	myStr += 'ay';
  }

  return myStr;
}
2 Likes

@camperextraordinaire you’re right, my bad. Im at the beginning of my coding adventure and got overexcited, I guess, haha. I will keep it in mind for the future, though.

what does this (.*) do in the expression?

okay yes I am aware of what this(*) does but not the this( . )

Okay I just read about it, I get it now thanks

Its interesting the several ways to use regex, be it to look after characters or just test the existence.

I did another way using for but it is not smart enough. Also, thanks for showing .search()

function translatePigLatin(str: string) {
  let regex = /[aeiou]/gi;

  if (regex.test(str[0])) {
    str += "way";
  } else if (str.match(regex)) {
    str = str.replace(/([^aeiou]+)(\w*)/, "$2$1" + "ay");
  }

  if (!regex.test(str)) str += "ay";

  return str;
}

Here is another way.

function translatePigLatin(str: string) {
  let regex = /[aeiou]/gi;

  if (regex.test(str[0])) {
    str += "way";
  } else if (str.match(regex)) {
    str = str.slice(str.search(regex)) + str.slice(0, str.search(regex)) + "ay";
  }

  if (!regex.test(str)) str += "ay";

  return str;
}

This my take on it using regex. Feels like a hack but it works

function translatePigLatin(str) {
  var regex = /^[^aeiou]+(?=[aeiou]|)/
  var string = str.match(regex) || "w"
 
  return str
    .replace(regex, "")
    .split("")
    .concat(string + "ay")
    .join("")
}

translatePigLatin("try");

This worked for me.

// Intermediate Algorithm Scripting: Pig Latin

function translatePigLatin(str) {

  // Find one or more consonants at the beginning
  let cons_arr = str.match(/^[^aeiou]+/);

  if(cons_arr){
     let cons_str = cons_arr.join();
     return str.substr(cons_str.length, str.length) + cons_str + 'ay';
  }
  else{
    return str + 'way';
  }

}

console.log(translatePigLatin("glove"));

Could you explain a little more the part of
else if (str.search(/[aeiou]/) > 0)
Please!!
Thank you!

My solution below + the explanation below that. It’s very regex heavy! I also opted for ternary operators instead of if statements since I never really use them!

function translatePigLatin(str) {
  return /^[^aeiou]/.test(str)  
    ? /^[^aeiou]+$/.test(str)   
      ? str + "ay" 
      : str.replace(/([^aeiou]*)(\w+)/, "$2$1" + "ay") 
    : str + "way";
}

translatePigLatin("algorithm");

Explanation:

RETURN If the first character is not a vowel then...
  ? test the whole string and see if it has no vowels
    ? if it has no vowels, add "ay" at the end of the word.
    : if it has some vowels, search for the first group of consecutive consonants and move it to the end of the string. then add "ay" at the end of the string
  : if the word begins with a vowel, add "way" at the end of the string.
function translatePigLatin(str) {
  let regex = /^[^aeiou]+/
  let matched = str.match(regex)
  if (str.match(regex)){
    return str.replace(regex, "").concat(matched + "ay");
  } else{
    return str.concat("way")
  }
}

regex = matching starting characters that aren’t vowels.
matched = to catch the said characters.
if the str start with characters that aren’t vowels, replace those consonants with nothing ("") and concat those consonants at the end, adding “ay”.
else, just concat “way” at the end!