0
if (event.keyCode === 38 || event.keyCode === 33 || event.keyCode === 40 || event.keyCode === 34) {
}

How to shorthand this code? Remember that conditional switch statements are slow.

I want to do something like

if (event.keyCode === 38 || 33 || 40 || 34)
Community
  • 1
  • 1
Szymon Toda
  • 4,454
  • 11
  • 43
  • 62
  • 16
    `Remember that conditional switch statements are slow` Huh? – SLaks Nov 27 '13 at 19:45
  • 1
    You want to shorten it for what? Execution time? number of characters? Is there actually a problem with what you have? – jcsanyi Nov 27 '13 at 19:47
  • 3
    Yes, could you explain that? I remember a bug in Mozilla's implementation that caused `switch` to be slower than `if`/`else` in certain cases, but I don't understand "conditional `switch` statements are slow" as a general statement... – Mark Reed Nov 27 '13 at 19:49
  • Use a hash so that you can use `event.keyCode` directly as hash key. Prepare the hash like this: `{38:true,33:true,...}`. Now all you have to do is ask `if (myHash[event.keyCode]) {...}` – Mörre Nov 27 '13 at 19:50
  • Considering that this appears to be code in a key-based event handler, I doubt that performance at that level is a rational concern. – Blue Skies Nov 27 '13 at 19:51
  • 2
    To people minusing this question, be so polite and state why. – Szymon Toda Nov 27 '13 at 19:53
  • Provided link for switch statements are slow: http://stackoverflow.com/questions/6665997/switch-statement-for-greater-than-less-than – Szymon Toda Nov 27 '13 at 19:54
  • @Ultra: I don't know where you're getting your information that switch statements are slow. I highly recommend you read this if you're concerned about performance with conditionals: http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html#fast_conditionals – Phil Nicholas Nov 27 '13 at 19:55
  • 1
    I have no idea why people would downvote this question. It's a good question and the answers are informative and useful. Favorited and +1 – cssyphus Nov 27 '13 at 19:56
  • @jcsanyi read last paragraph of question "I want to do something like ..." – Szymon Toda Nov 27 '13 at 19:56
  • 1
    @Ultra - your link states `[switch-immediate] is pretty fast in all tested environments, and actually the fastest in MSIE.`. Is that not what you could do? – admdrew Nov 27 '13 at 19:56
  • @Blue Skies it's just an example of usage. – Szymon Toda Nov 27 '13 at 19:56
  • @admdrew can't imageine [switch-immediate] statement in that case. – Szymon Toda Nov 27 '13 at 19:58
  • 1
    @Mörre it is a proper answer deserving to be separated from comments section. – Szymon Toda Nov 27 '13 at 19:58
  • @Ultra - why not? Your `case`s will be the integer `KeyCode` values. – admdrew Nov 27 '13 at 20:00
  • @jcsanyi Did you intend for your comment to sound so peevish? Undoubtably there are situations (however rare) where the time difference between `if` and `switch` could be important, but ignoring that why is it wrong to ask this question even for purely academic reasons? – cssyphus Nov 27 '13 at 20:00
  • 1
    possible duplicate of [How to make this if statement shorter?](http://stackoverflow.com/questions/2218844/how-to-make-this-if-statement-shorter) – Blue Skies Nov 27 '13 at 20:05
  • Searching for `"javascript shorter if statement"` provides plenty of results. – Blue Skies Nov 27 '13 at 20:06
  • @admdrew just see how much keyCodes is there to check. – Szymon Toda Dec 07 '13 at 12:09

5 Answers5

13

I actually recommend using a switch. The general rule of thumb is

  • 1 or 2 values: use an if
  • 3 to 10 values: use a switch
  • 11 or more: use an array lookup

But since you're using jQuery, you can simply do:

jQuery.inArray(event.keyCode, [38,33,40,34])
corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • Conditional statements are slow. Anyway could you present an switch markup for that? – Szymon Toda Nov 27 '13 at 19:48
  • 2
    Ultra, please read the link I provided. It addresses the concern about what will be the fastest. – corsiKa Nov 27 '13 at 19:49
  • There's no good way for `switch` with case presented in this question. – Szymon Toda Nov 27 '13 at 19:52
  • In any event, you're using jQuery - you don't need to do this yourself. – corsiKa Nov 27 '13 at 19:53
  • You forgot hashes (simple JS objects). Easier and faster than arrays - the value to check for is the key you store in the prepared array, with a "truthy" value for that key. Now you can have a direct if-statement which uses the JS engine's built-in hash algorithm - very little code, and you won't get it done any faster any other way. – Mörre Nov 27 '13 at 20:05
  • @Mörre Umm, instead of hashes it would be easier to just use an object with members: they're stored internally in a hashmap. – corsiKa Nov 27 '13 at 20:30
  • @corsiKa What did I say? I said hashes. Hashes in Javascript ARE objects. I even said so: "(simple JS objects)". – Mörre Nov 27 '13 at 21:40
  • @Mörre Oh I see, sorry I completely misread what you said. Yes, you absolutely could do that: that's what the third option is supposed to be in the bullet list. – corsiKa Nov 27 '13 at 22:18
7

Using pure JavaScript, you could do something like this:

if ([38,33,40,34].indexOf(event.keyCode) >= 0) { ... }

But keep in mind that this method was introduced with ECMAScript 5, and so isn't supported by some older browsers.

You could also do something like this, which should work on older browsers as well:

if ({38:1,33:1,40:1,34:1}[event.keyCode]) { ... }
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
5

You could use an object lookup.

if ({33:true,34:true,38:true,40:true}[event.keyCode]) {
    ...
}
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • 1
    Who voted this down (-1 right now)? Care to leave an explanation? Today a lot of downvoting seems to happen all across this site, I had to review a LOT of completely valid Qs and As flagged as "low quality" by some idiot(s). – Mörre Nov 27 '13 at 19:58
  • 1
    I'd probably use `1` instead of `true` just to keep it shorter. – Blue Skies Nov 27 '13 at 20:00
  • @BlueSkies sure, but since the important values are numeric, I wanted them to be more distinct from the boilerplate. – Mark Reed Nov 27 '13 at 21:20
  • @Ultra: Did you read the comment above yours? I just said I'd probably use `1` to keep it short. Your question is about making it shorter after all, right? If you want clear, then you could just assign `event.keycode` to a variable and use `key == 33 || ...` – Blue Skies Dec 07 '13 at 13:44
  • @BlueSkies in that case thank you for creativity, yet I stated exacly what shorting I looking for – Szymon Toda Dec 07 '13 at 14:07
1

Here's an improved solution that uses ES6 Array.prototype.includes():

[B, C].includes(A)

Your example:

[38, 33, 40, 34].includes(event.keyCode)

S. Emmer
  • 93
  • 7
0

You can use regular expressions, although I'm not sure if that's necessarily faster than a switch statement.

if (/^(38|33|40|34)$/.test(event.keyCode)) {
 // Some code here
}

Though it's much more readable than doing an object property look-up.

linstantnoodles
  • 4,350
  • 1
  • 22
  • 24