1
\$\begingroup\$

So I needed to write a function that takes a string and returns a javascript object with vowels and consonants properties that maps to the number of vowels and consonants in the string

function getCount(words) {
  let answer = {vowels: 0, consonants: 0};
  if( typeof words !== 'string') { return answer }

  let vowel  = 'aeiouAEIOU'

  for(char of words){
    if(char === ' ') { continue }
    if(vowel.indexOf(char) === -1){  // not a vowel
      answer.consonants += 1
    }
    else if(vowel.indexOf(char) !== -1){  // is a vowel
      answer.vowels += 1
    }
  }
  return answer
}

Is there a better way of going about it? Preferably a functional approach

\$\endgroup\$
1
  • \$\begingroup\$ Not everything that is neither a space nor a vowel is a consonant. \$\endgroup\$
    – Rainer P.
    Commented May 11, 2016 at 19:55

1 Answer 1

5
\$\begingroup\$

This avoids loops completely and expresses your intent more clearly, I think.

Also, note that you should explicitly define the valid consonants, so that you will properly ignore numbers, punctuation, etc.

function getCount(words) {
  var words      = (typeof words == 'string') ? words : '',
      count      = re => (words.match(re) || []).length,
      vowels     = count(/[aeiou]/ig),
      consonants = count(/[bcdfghjklmnpqrstvxzwy]/ig);

  return {vowels, consonants};
}
\$\endgroup\$
2
  • \$\begingroup\$ Oh that's beautiful ^_^. Just explain why the arrow function in count is 'ored' with an empty list? \$\endgroup\$
    – MAA
    Commented May 11, 2016 at 21:33
  • \$\begingroup\$ When match fails to match, it returns null, and since you can't take the .length property of null, I return an empty list instead, which will have a length of 0. \$\endgroup\$
    – Jonah
    Commented May 11, 2016 at 21:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.