DEV Community

Julian Toscani
Julian Toscani

Posted on • Updated on

TIL: The easiest way to handle index overflow...

TLDR;

You can use the modulo operator in conjunction with the length of the array. This requires you to set you position after every change.

handleOverflow(options, chosen) {
 return (options.length + chosen) % options.length
}
Enter fullscreen mode Exit fullscreen mode

Recently, I was working on a search input with an autocomplete feature. One of the requirements was that users should be able to cycle through the options by pressing arrow keys. Additionally, if you were at the last item and pressed down it should jump to the first item in the list. Similarly, if you were at the first element and pressed up it should jump to the last item.

First Solution

The Mental Model

  1. I have an array of options
  2. I have a numerical value to access one element of that array, the index
    1. In order to get the next element I increase the index.
    2. In order to get the previous element I decrease the index.
  3. If the index gets below 0 I need to jump to the end
  4. If the index gets bigger than the index of the last element, I need to jump to first element.

Solution

handleOverflow(options, chosen) {
  let next = chosen;

  if (next > options.length - 1) {
    next = min;
  }

  if (next < 0) {
    next = max;
  }

  return next;
}
Enter fullscreen mode Exit fullscreen mode

What I did not like about the implementation

  1. It is verbose
  2. I have to reset a value inside of the function

'Improving' the solution

What basically happens is that I need to access an element in a list with a known size. So basically, I only need to worry about the size of the array and the position I am at.

So, if I am at position 5 (meaning the 6th element) in an array with 6 elements and I want to go to the next element I go to index 6. Unfortunately, that does not exist so I go back to the start which is at index 0. I know that 6 % 6 equals 0. Hence, accessing the array by index % array.length would work for positive numbers.

With negative numbers, that does not work unfortunately as -1 % array.length equals -1 so even by removing the - I would land at the first element, not the last. This forces me to add the length of the array to the result of the modulo operation and BAM, we have the solution:

handleOverflow(options, chosen) {
 return (options.length + chosen) % options.length
}
Enter fullscreen mode Exit fullscreen mode

What do you think about this solution?
Is it better or worse than the first?
How would you handle this problem?

Best and Happy Holidays!

Top comments (0)