4

was wondering if there is a better way to write the code below. I want my if statement to ignore all of the keycodes. but seems quite a messy way to write it as below.

thanks!

if (event.keyCode === 9 
   || event.keyCode === 91 
   || event.keyCode === 20 
   || event.keyCode === 18 
   || event.keyCode === 17 
   || event.keyCode === 37)
user14063792468
  • 839
  • 12
  • 28
user11751578
  • 81
  • 1
  • 7

5 Answers5

10

Using includes:

if ([9, 91, 20, 18, 17, 37].includes(event.keyCode))
blex
  • 24,941
  • 5
  • 39
  • 72
  • In terms of performance, I would highly recommend you should use `indexOf` instead https://stackoverflow.com/questions/47659972/array-indexof-vs-includes-perfomance-depending-on-browser-and-needle-positio @blex – Nguyễn Văn Phong Apr 15 '21 at 02:45
  • @NguyễnVănPhong you're overthinking ;) Yes, it might make sense if you have thousands of values that you have to check a thousand times. We're talking about key strokes here. `includes` exists for a reason: to make your code easier to understand – blex Apr 15 '21 at 02:57
  • @blex Yeah. It's just another aspect of computer science - `performance, time/space complexity, etc..`. And yes, `includes` work as well :) – Nguyễn Văn Phong Apr 15 '21 at 03:00
5

For a larger list of values that you compare with often, it may be more optimal to use a Set.

const codes = new Set([9, 91, 20, 18, 17, 37]);
if(codes.has(event.keyCode)){
   // do something
}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • 1
    In case anyone doesn't know why it will be more optimal `has` is an O(1) operation while `includes` is O(n), since Sets have an O(1) search time, while Arrays have an O(n) search time. The speed improvement may not be that evident for a small number of elements like in this case, but it is good practice regardless and according to this post even at 10 elements `has` is slightly faster: https://dev.to/arnaud/using-array-prototype-includes-vs-set-prototype-has-to-filter-arrays-41fg – Sash Sinha Apr 15 '21 at 04:28
4

You can use Array#some or Array#indexOf instead.

if ([9, 91, 20, 18, 17, 37].some(val => val === event.keyCode))

or

if ([9, 91, 20, 18, 17, 37].indexOf(event.keyCode) !== -1)

In terms of performance, I would highly recommend you should use indexOf.

And another aspect you should take care of is between includes and indexOf in case of NAN issue. There are 2 posts below that can help you have comprehensive knowledge about them:

Nguyễn Văn Phong
  • 13,506
  • 17
  • 39
  • 56
  • `includes` is more performant than `some` or `indexOf` – arieljuod Apr 15 '21 at 02:20
  • I'm not sure :) @arieljuod – Nguyễn Văn Phong Apr 15 '21 at 02:23
  • I've updated my answer with some docs related to performance, Pls kindly take a look at it @arieljuod – Nguyễn Văn Phong Apr 15 '21 at 02:41
  • Keep in mind that those benchmarks results are from 2017, this benchmark shows a really big difference in performance for includes https://www.measurethat.net/Benchmarks/Show/6029/0/some-vs-filter-vs-indexof-vs-includes with the current Chrome version and only a slightly worst performance with the current firefox, but yes it depends on the browser (though with that difference for chrome I would still go with includes over indexOf) – arieljuod Apr 15 '21 at 03:56
  • Agree. It really depends on specific browser implementation. @arieljuod – Nguyễn Văn Phong Apr 15 '21 at 10:28
3

Like others have said, you can create an array or set with the valid key codes and test for membership using the event.keyCode variable. I wrote some example code below for how you could do this in a clean way :)

// let eventKeyCode = event.keyCode;
let eventKeyCode = 28;
let validKeyCodes = [9, 91, 20, 18, 17, 37];
if (validKeyCodes.includes(eventKeyCode)) {
  // do something 
  console.log(`event has valid key code: ${eventKeyCode}`);
} else {
  // catch logic
  console.log(`event has invalid key code: ${eventKeyCode}`);
}
Peterg17
  • 31
  • 2
1

You can pass the if logic into a function.

function isValidKey(keyCode) {
  const validKeys = [9, 91, 20, 18, 17, 37];
  return validKeys.includes(keyCode);
}
//...
if (isValidKey(event.keyCode)) ...
Ignacior
  • 897
  • 2
  • 15