Creating indexes from a theoretical decimal/int, splitting into before and after arrays I'm currently populating before and after arrays with indexes, based on a number provided. If the input going in is an int, there will be three indexes (left, middle and right). If it is a decimal, there will just be two (left, right). There will me a maximum of three indexes to sort into a maximum of two arrays (before and after). To understand, here is some expected input/output:

input: 1
output: before [] after [0, 1, 2]

input: 1.5
output: before [] after [1, 2]

input: -3.4
output: before [3, 4] after []

input: 0
output: before [1] after [0, 1]


Essentially, the input index gets floored and ceiling'd (or, in the case of a whole number, their next/previous integers are used along with the original input). If any of the resulting integers are below 0, they get put in the before array, but their index is made absolute, otherwise they go into the after array. If they do get put into the before array, then they are put in to reverse order, such that they remain sorted in numerical order.

I have the below working code. But I feel like I could do much better. How would the community go about optimising this?



var input = document.getElementById('input');
var button = document.getElementById('button');
var ouput = document.getElementById('output');

function getOutput(input) {

  var left = Math.floor(input);
  var right = Math.ceil(input);
  var middle;

  var before = [];
  var after = [];

  if (right == left)
    left--,
    middle = left + 1,
    right = left + 2;

  if (left &lt; 0)
    before.unshift(Math.abs(left));
  else
    after.push(left);

  if (middle &lt; 0)
    before.unshift(Math.abs(middle));
  else if (typeof middle == 'number')
    after.push(middle);

  if (right &lt; 0)
    before.unshift(Math.abs(right));
  else
    after.push(right);

  return {before: before, after: after};
  
}

function buttonPressed () {
  
  var i = parseFloat(input.value);
  var msg = 'not a number';
  
  if (!isNaN(i)) {
    
    var o = getOutput(i);
    
    msg = 'before [' + o.before.toString() + '] ahead [' + o.after.toString() + ']';
  
  }
  
  ouput.innerHTML = msg;
  
}
&lt;input id="input" type="text"&gt;
&lt;input id="button" type="button" value="get" onclick="javascript:buttonPressed();"&gt;
&lt;br&gt;&lt;br&gt;
&lt;div id="output" style="font-family: monospace;"&gt;&lt;/div&gt;




My interest is in the getOutput method. The other stuff is for demonstration purposes.

Update

I have adjusted the expected output and the code from the original question, after being prompted to rethink from the comments.
The code in the question seems to have adequate complexity for the getOutput function. Some small hints may be given, like:


do not use comma-expressions and decrement,
initialize middle with null and check for it with !== instead of typeof,
also, I do not like comparing undefined middle with 0.


The current code is more or less readable.

As for optimizations, one observation is that apart from [-1, 1] range, all other inputs always use the same alternative, making unnecessary to check left, right and middle individually. (eg, if right &lt; 0, then so are middle and lift). How much optimization it really brings is hard to tell. If input numbers are almost always large, then making separate branch and constructing an array directly [left, middle, right] may make the code more efficient.

The near-zero case may need more conditions, of course (or just some kind of lookup for ready arrays - as the number of cases is small).

If you want a more compact code, maybe something like this can be done:

 tmparray = ((right == left) ? [left-1, left, left+1] : [left, left+1]);


And after that push/unshift in a loop for each tmparray element. Not sure this will be faster though, but at least may be more readable. (left may be renamed to "lower", and right calculated inline only in the condition).