2

I have a code like this:

if (action == 'John' || action == 'John Beckham' || action == 'Henry John'){
     alert('true!');
}

How do I minimize this code?

Should work in IE7.

Jasper
  • 5,090
  • 11
  • 34
  • 41
  • It's hard to see where your stuck here. What did you try? Where are you struggling? – Alexander R Feb 25 '13 at 12:12
  • 2
    You could remove the spaces ;-) and use a variable `a` instead of `action`... – Uooo Feb 25 '13 at 12:16
  • You original question text was more clear than the current phrasing. It provided an example of what you wanted to achieve, which was checking set membership instead of checking each possible value directly (`action ∈ [a,b,c]` instead of `action == a || action == b ...)` – Simen Echholt Feb 25 '13 at 12:20
  • I've updated it, because action is always different but may consist of the same words in different direction. – Jasper Feb 25 '13 at 12:26

7 Answers7

8

If "John" always appears, the simplest thing is:

if (action.toLowerCase().indexOf("john") !== -1) {
    // Do something
}

...but as your question has already changed the values against which you're checking action once, I hesitate to assume that. Also note that it will match "xxxjohnxxx", which may not be what you want.

Original suggestions (updated for new action values from your edit):


There are lots of ways, all shown using case insensitivity since you mentioned that in the comments:

String#indexOf:

if ("|john|john beckham|john henry|giggs john|scholes john|john messi|".indexOf("|" + action.toLowerCase() + "|") !== -1) {
    // Do something
}

Regular expressions:

if (/^(?:John|John Beckham|John Henry|Giggs John|Scholes John|John Messi)$/i.test(action)) {
    // Do something
}

Because you're just using the true/false result, I'm using test which just returns true/false, instead of exec which returns matching results. Both work in this case, but the browser may be able to ever-so-slightly optimize test (but then, regex is unlikely to be the best solution if your goal is the fastest result or the least memory use).


Or a switch:

switch (action.toLowerCase()) {
    case "john":
    case "john beckham":
    case "john henry":
    case "giggs john":
    case "scholes john":
    case "john messi":
        // Do something
}

Or an object lookup:

var actions = {
    "john":         true,
    "john beckham": true,
    "john henry":   true,
    "giggs john":   true,
    "scholes john": true,
    "john messi":   true
};

if (actions[action.toLowerCase()]) {
    // do something
}

(That also has the advantage of letting you say what to do — e.g., the true could be replaced with a function you call.)


Or (on an ES5-enabled environment or with an ES5 shim) Array#indexOf:

if (["john", "john beckham", "john henry", "giggs john", "scholes john", "john messi"].indexOf(action.toLowerCase()) !== -1 {
    // Do something
}

or since you use jQuery, you can avoid the shim on older browsers by using inArray:

if ($.inArray(action.toLowerCase(), ["john", "john beckham", "john henry", "giggs john", "scholes john", "john messi"]) !== -1) {
    // Do something
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • The regex (horrible solution) can be sortened to `[a-g]` and it would be a good idea to have a `default` in that switch – Griffin Feb 25 '13 at 12:15
  • I've updated a question, none of the examples in your code would work. – Jasper Feb 25 '13 at 12:16
  • @Griffin: I was giving the OP lots of choices. Re the switch, a `default` is fine, but not necessary, as there was no `else` shown in the question. – T.J. Crowder Feb 25 '13 at 12:16
  • The only way to optimize this seems to be a one line regexp – Jasper Feb 25 '13 at 12:16
  • only switch will work, but it's huge. indexof can't be used because of ie7. – Jasper Feb 25 '13 at 12:21
  • @Steve: No, most of them still apply, not just `switch`. Updated with examples. – T.J. Crowder Feb 25 '13 at 12:22
  • 1
    @T.J very good answer but because of cut cut its not looking good. I feel you should remove that part – Grijesh Chauhan Feb 25 '13 at 12:36
  • @T.J.Crowder And you can see magic as you remove you will get +1 :) – Grijesh Chauhan Feb 25 '13 at 12:37
  • Yeah, I'd vote this +1 if the author removes everything but `$.inArray`, which is the only one that actually answers the Q – nice ass Feb 25 '13 at 12:38
  • $.inArray seems to be a slower solution than regexp – Jasper Feb 25 '13 at 12:39
  • @OneTrickPony: Why is it the only one that answers the question? All of the others are also valid, useful approaches. And offer more to work with should a similar thing come up for him in the future, but where he needs (say) the further information the object lookup can give him. – T.J. Crowder Feb 25 '13 at 12:40
  • @Steve: When editing, I forgot to remove the `[]`. Fixed: http://jsfiddle.net/CqxcA/3/ – T.J. Crowder Feb 25 '13 at 12:41
  • works now, thanks. Any chance to make it work for both `John` and `john`? – Jasper Feb 25 '13 at 12:44
  • @Steve: Add the `i` flag: `/John|John Messi/i.test(...)` – T.J. Crowder Feb 25 '13 at 12:45
  • @Steve Sorry, but this regexp will hurt you if you have names with extra chars at the start or end: Check this fiddle: http://jsfiddle.net/CqxcA/4/ – Beat Richartz Feb 25 '13 at 12:51
  • @Steve: Turns out all of my original solutions applied, I've added back the `String#indexOf` option (the only one I actually removed). I'm not saying I'd use it, just saying it's an option. :-) – T.J. Crowder Feb 25 '13 at 13:03
3

if using jquery, then you could do:

var arr = ['a','b','c','d','e','f','g'];
if( $.inArray(action, arr) !== -1 ) {
  alert("true");
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
  • This is the best way, since it will use native `indexOf` if available in modern browsers, and does not require shim for IE7. – dfsq Feb 25 '13 at 12:15
  • Almost the best answer, because OP tagged this with jQuery, but `$.inArray` may return 0 if the action is the first element in the array, and that evaluates to false. You should check if < 0 (-1) – nice ass Feb 25 '13 at 12:24
  • what about a regex like `/one|two|three|four|five/`? – Jasper Feb 25 '13 at 12:24
2

Try this, it uses indexOf:

if (['a', 'b', 'c', 'd', 'e'].indexOf(action) > -1) {
  alert(true);
}

Update: If you want to support IE7 and below, use the answer to this question

If you're using jQuery, you can use $.inArray like this:

if ($.inArray(action, ['a','b','c','d') > -1) {
  alert(true);
}

UPDATE

You can also use a regexp with test (The group makes the regexp not match "John Langhammerer" / actions with extra chars to the ones to be matched):

if ((/^(John Langhammer|Piet Krauthammer|Some Guy)$/i).test(action)) {
  alert(true);
}

UPDATE: /i makes the regexp case insensitive.

Below is a solution which would have worked for one-char actions:

You can also use String.indexOf which is supported in IE7 (if your actions are all one char):

if ('abcde'.indexOf(action) > -1) {
  alert(true);
}
Community
  • 1
  • 1
Beat Richartz
  • 9,474
  • 1
  • 33
  • 50
1

Make an array as below.

var newAry = array('a','b','c');

Now just check it as below.

$(function()
{
    var newAry = Array('a','b','c');
    if($.inArray(action,newAry)){ alert(action); }
});
Dipesh Parmar
  • 27,090
  • 8
  • 61
  • 90
1

Cross-browser solution:

if ( action in {'John':1, 'John Beckham':1, 'John Henry':1, 'Giggs John':1, 'Scholes John':1, 'John Messi':1 } ){
     alert('true!');
}
oleq
  • 15,697
  • 1
  • 38
  • 65
1

In addition of indexOf, you can also use conditional operator in Javascript.

names = ['John' , 
         'John Beckham', 
         'John Henry' , 
         'Giggs John' , 
         'Scholes John', 
         'John Messi'
];
names.indexOf(action) != -1? alert('True') : alert ('False');

And you want to do more then simple statement do like:

 names.indexOf(action) != -1? doSomethingOnTrue() : doSomethingOnFalse(); 
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
0
if('abcdefg'.indexOf(action) > -1){
    // action is one of 'abcdef'
}
Alen Genzić
  • 1,398
  • 10
  • 17