0

I’m trying to write something that checks that letters are not equal to vowels. I know I can do this with regular expressions, but for the sake of learning more about conditional statements, how could I write something like this more efficiently?

if (myArray[i] !== "a" || myArray[i] !=="e" || myArray[i] !=="i" || myArray[i] !=="o" || myArray[i] !=="u") {
    console.log(myArray[i] + "");
}

By more efficient I mean more DRY without the myArray[i] !== "a" being repeated so much.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Chirpizard
  • 291
  • 3
  • 17
  • 5
    Well first thing to do is use `&&` instead of `||`, because the logic as written doesn't make sense. – Pointy Nov 30 '15 at 16:26
  • 2
    `switch` would be a better choice – Ramanlfc Nov 30 '15 at 16:27
  • note that `||` doesn't shortcircuit: if it fails, the next might succeed, so you will always run through all the checks. That makes this code run much slower than a regex. – Mike 'Pomax' Kamermans Nov 30 '15 at 16:27
  • 1
    @Mike'Pomax'Kamermans although in this case it will **always** succeed within the first two checks. Any value other than "a" will evaluate true on the first, and "a" will evaluate true on the second: this statement will always evaluate as true. – Jon Story Nov 30 '15 at 16:30
  • @PeterRader there's no such thing as `!===` :) – Pointy Nov 30 '15 at 16:35

3 Answers3

8

One nice way to do this is to put all vowels in a string and use indexOf:

if ("aeiou".indexOf(myArray[i]) === -1) {
    // Do a thing if myArray[i] is not a vowel
}

If you need case insensitivity, use myArray[i].toLowerCase().


As mentioned by Mike 'Pomax' Kamermans in a comment for this answer, it's better and faster to use regex to check the entire string for vowels instead of checking each individual character. That solution would look something like:

if (!myString.match(/[aeiou]/) {
    // Do a thing if myString doesn't have any vowels
}
Rahat Ahmed
  • 2,191
  • 2
  • 30
  • 40
  • Thanks for this, I knew there had to be a better way. – Chirpizard Nov 30 '15 at 16:33
  • 3
    One thing to note is that although this is short and does work, it is not very intuitive: unless you know this trick, somebody else may have to take a moment to work out what you're trying to do. That's not usually desirable! – Jon Story Nov 30 '15 at 16:34
  • True, it does require a bit more thought, but it's certainly more readable than the OP's original code. IMO the tradeoff is worth it, but it's up to you to decide that. – Rahat Ahmed Nov 30 '15 at 16:36
  • 1
    That's what comments are for! Nothing wrong with using an unintuitive method if the code includes a simple comment stating what it's doing. – Ieuan Stanley Nov 30 '15 at 16:38
  • 1
    While it's certainly preference, at the very least it needs a clear explanation of what you're trying to do. If you're going to do this, comment it well! (edit: @IStanley got there before me) – Jon Story Nov 30 '15 at 16:38
  • 1
    @Chirpizard for learning purposes, a nice trick to know, but this is not a "better" way so much as "a way". A *better* way is (as you've already hinted) using a regex match: while this solution checks letter by letter, and is very slow, using `"your original string".match(/[aiueo]/)` checks the entire string in a single, fast pass. – Mike 'Pomax' Kamermans Nov 30 '15 at 16:50
  • @Mike'Pomax'Kamermans That's great to know. Thanks for sharing! – Chirpizard Nov 30 '15 at 16:51
  • What if I wanted to modify this to check for any "falsy" values? – Chirpizard Dec 07 '15 at 02:11
2

try,

//the myArray[i] is not a vowel
if (["e","e","o","i","u"].indexOf(myArray[i]) === -1 ) {
    console.log(myArray[i] + "");
}
Azad
  • 5,144
  • 4
  • 28
  • 56
0

You can make an array of vowels and then search if your key is inside the array.

var arrVowels = ['a','e','i','o','u'];
var myArray = ['b'];
if(!in_array(myArray[0], arrVowels)) {
    alert(" is not in the array! ");
}

function in_array(needle, haystack) {
  var key = '';
  for (key in haystack) {
    if (haystack[key] == needle) {
      return true;
    }
  }

  return false;
}

EDIT

To all critic people, see more about in_array() function:

http://phpjs.org/functions/in_array/

Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
  • 1
    I think `.indexOf()` would be a little easier. Also, it's not good practice to use `for ... in` on JavaScript arrays. – Pointy Nov 30 '15 at 16:30
  • Report it to phpjs.org. Tons of expert people use `for..in` in certain situations. That situation is not dangerous. – Marcos Pérez Gude Nov 30 '15 at 16:31
  • You're over-complicating this answer by introducing a strict comparison - the OP is comparing to simple strings – Jon Story Nov 30 '15 at 16:32
  • @JonStory that's a correct code. Maybe `indexOf` is simplest, but this function is reusable in anywhere. – Marcos Pérez Gude Nov 30 '15 at 16:33
  • 1
    phpjs is a blight on the world of web programming. And the point of avoiding `for ... in` on arrays is that you don't know whether it's dangerous or not. – Pointy Nov 30 '15 at 16:36
  • I'm not saying to use indexOf (which is not intuitive), I'm saying you're giving an option of a strict `===` comparison or `==`, when you don't need to and that over-complicates the function. You could just use ONE of `===` or `==` without the strict parameter and have a simpler function with higher performance. I know what you mean that this function can be used for any haystack/needle, but for the original question it's over-complicated code. At the very least you should use `argstrict = true` or `argstrict = false` to make the parameter optional. – Jon Story Nov 30 '15 at 16:37
  • I love strict mode, but maybe you have a piece of truth. Overcomplicated I don't know, in my opinion is a full-feature function. It's not mine, it's from phpjs.org library that includes a lot of useful functions in javascript copied from php. I will edit the answer without the parameter and all happy :) – Marcos Pérez Gude Nov 30 '15 at 16:41