Printing elements that don't satisfy condition

Viewed 63

I'm trying to complete a HackerRank challenge that involves printing a list of elements of an array starting with all the vowels then all the consonants but I'm having trouble with that.

function vowelsAndConsonants(s) {
    var str = s;
    var arr = str.split("");
    var i;
    var vow = ["a","e","i","o","u","y"];
    var con = ['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','z']
    for (i = 0; i < arr.length; i++) {
        for (var j = 0; j< vow.length; j++){
            if (arr[i] === vow[j]){
                console.log(arr[i])
            }
            
        }
    
    }
} 

This is what I get from the code above, but I can't print the consonants. The input string is "javascriptloops"

a
a
i
o
o

I also tried this

function vowelsAndConsonants(s) {
    var str = s;
    var arr = str.split("");
    var i;
    var vow = ["a","e","i","o","u","y"];
    var con = ['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','z']
    for (i = 0; i < arr.length; i++) {
        for (var j = 0; j< vow.length; j++){
            if (arr[i] === vow[j]){
                console.log(arr[i])
                break;
            }
            
        }
    
        for (var j = 0; j< con.length; j++){
            if (arr[i] === con[j]){
                console.log(arr[i])
            }
                
        }
    }
          
}

But here's what I had

j
a
v
a
s
c
r
i
p
t
l
o
o
p
s
6 Answers

It's a good idea to define the smaller subset (vowels) and treat the rest of the letters of the alphabet as consonants.

Also, naming your variables goes a long way in readability

function vowelsAndConsonants(s) {
  var letters = s.split("");
  const vowels = ["a", "e", "i", "o", "u", "y"];
  for (const letter of letters) { // we are cycling through the letters to find all vowels
    for (const vowel of vowels) { // now we are cycling through the list of vowels
      if (letter === vowel) { // if we found a vowel in the vowel list, print it and stop searching for other vowels (break)
        console.log(letter);
        break;
      }
    }
  }

  // Searching for consonants is trickier
  for (const letter of letters) { // we cycle again through the letters
    let consonant = true; // we assume that the letter is consonant until it's proven otherwise

    for (const vowel of vowels) { // cycling through the list of vowels
      if (letter === vowel) { // if we found that the letter is vowel
        consonant = false; // we set the flag to false
        break; // and stop searching more as we know already that it is a vowel
      }
    }

    if (consonant === true) { // if after cycling we realized that this is a consonant, and not a vowel - print it
      console.log(letter)
    }
  }
}

vowelsAndConsonants("normal");

An easy solution would be looping through twice:

function vowelsAndConsonants(s) {
    let vowels = ["a", "e", "i", "o", "u"];

    for(let v of s) {
        if(vowels.includes(v))
            console.log(v);
    }
    for(let v of s) {
        if(!vowels.includes(v))
            console.log(v);
    }
}

there is a solution, you can take a look

function vowelsAndConsonants(s) {
    var str = s;
    var arr = str.split("");
    var vow = ["a","e","i","o","u","y"];
   
    
    const ordered = arr.reduce( (res, letter) => {
      if (vow.includes(letter)) {
        return {...res, vow: [...res.vow, letter]}
      }

      return {...res, con: [...res.con, letter]}
    }, { con: [], vow: []});
    
    return ordered.vow.join('') + ordered.con.join('');
} 

Your outer loop needs to run twice.

This solution also uses for ... in loops and array.includes(), which is a little cleaner than nesting standard for loops.

const vowelsAndConsonants = s => {
  const vow = ['a','e','i','o','u','y'];
  for (const c of s)
    if (vow.includes(c))
      console.log(c)
  for (const c of s)
    if (!vow.includes(c))
      console.log(c)
}
    
vowelsAndConsonants('javascriptloops')

const f = s => {
  const isVowel = char => ['a', 'e', 'i', 'o', 'u'].includes(char);
  const letters = s.split('');
  const consonants = letters.reduce((result, letter) => {
    if (isVowel(letter)) console.log(letter);
    else result.push(letter);
    return result;
  }, []);
  consonants.forEach(c => console.log(c))
}

f('javascriptloops');

You can use filter() instead of loops:

var vow = ['a','e','i','o','u','y'].join('');
var str = 'javascriptloops'.split('');

console.log(str.filter(x => vow.includes(x)));   // vowels
console.log(str.filter(x => !vow.includes(x)));  // consonants (not vowels)

Related