A function to find temperatures closest to zero I wrote this function that, given an array, calculates the closest number to zero. The conditions are the following:


if the array is empty, return 0
if the array has two values share the "closeness" to zero, return the positive (for example if -1 and 1)


Here is my code and link to it.



// Write a function that takes an array an finds the closes number to 0. 
// Disregard all 0s
// If the array is empty return 0

const tempArray = [-1, 0, 0, 5, -5, 6, -3, 2, 10, 13, 8, 70, -36, 36];

function calculateClosestTo0 (tempArray) {
  let minusTemps = [];
  let plusTemps = [];

  if (!tempArray.length) {
    return 0;
  }

  for (let i = 0; i &lt; tempArray.length - 1; i++) {
    if (tempArray[i] &lt; 0) {
      minusTemps.push(tempArray[i]);
    } else if (tempArray[i] &gt; 0) {
      plusTemps.push(tempArray[i]);
    }
  }

  minusTemps.sort((a, b) =&gt; b - a)
  plusTemps.sort((a, b) =&gt; a - b)

  if (plusTemps[0] === Math.abs(minusTemps[0])) {
    return(plusTemps[0])
  }

  if (plusTemps[0] &lt; Math.abs(minusTemps[0])) {
    return(plusTemps[0])
  }

  if (plusTemps[0] &gt; Math.abs(minusTemps[0])) {
    return(minusTemps[0])
  }
}

calculateClosestTo0(tempArray)




What I intended to do is separate the array into minus values and positive values. The minus values I ordered by descending (cause I want the first item to be the "biggest" in minus numbers perspective) and the positive in ascending. After that, I compare the first number.

What worries me most is the I try to remove the "0" like that:

for (let i = 0; i &lt; tempArray.length - 1; i++) {
  if (tempArray[i] &lt; 0) {
    minusTemps.push(tempArray[i]);
  } else if (tempArray[i] &gt; 0) {
    plusTemps.push(tempArray[i]);
  }
}


My colleagues usually frowned upon having a condition that has "else if" and nothing else. Why, I don't know.

Another thing that worries me is that ending part, where I have 3 conditions to return the correct value. Is there a smarter way to do that?

And generally: do you think that there is a better approach to such a problem?
Bugs


The loop

for (let i = 0; i &lt; tempArray.length - 1 ; i++) {


omits the last array element, it should be

for (let i = 0; i &lt; tempArray.length ; i++) {

If all array elements have the same sign then 
either plusTemps or minusTemps is an empty array, and accessing
its first element in

if (plusTemps[0] === Math.abs(minusTemps[0])) {


is undefined. Those cases must be treated separately in your approach.
If the array is not empty, but all array elements are zero then
both plusTemps are minusTemps are empty, again making the result
undefined. What would be the expected result for this case?
Returning zero looks like a sensible choice to me.


Simplifications

The first and second check in

if (plusTemps[0] === Math.abs(minusTemps[0])) {
    return(plusTemps[0])
}

if (plusTemps[0] &lt; Math.abs(minusTemps[0])) {
    return(plusTemps[0])
}

if (plusTemps[0] &gt; Math.abs(minusTemps[0])) {
    return(minusTemps[0])
}


can be combined to 

if (plusTemps[0] &lt;= Math.abs(minusTemps[0])) {
    return(plusTemps[0])
}

if (plusTemps[0] &gt; Math.abs(minusTemps[0])) {
    return(minusTemps[0])
}


and the second if is better done with an else:

if (plusTemps[0] &lt;= Math.abs(minusTemps[0])) {
    return(plusTemps[0])
} else {
    return(minusTemps[0])
}


This saves a comparison and makes it clear that a value is returned
in any case. And since we know that minusTemps[0] is negative we need
not call Math.abs:

if (plusTemps[0] &lt;= -minusTemps[0]) {
    return(plusTemps[0])
} else {
    return(minusTemps[0])
}


A better approach

As already mentioned in the comments and in the other answers, the solution
can be determined with a single traversal of the array, without the need to
create additional arrays or any filtering or sorting.

Just keep track of the closest element found so far, and replace it if a
negative element with a closer distance is found, or a positive element
with the a closer or the same distance.

closest stays zero until the first non-zero array element is found.
If non non-zero element exists then zero is returned. This covers the case
of an empty array, making the check for the array length obsolete.

function calculateClosestTo0 (arr) {
    let closest = 0
    for (let i = 0; i &lt; tempArray.length ; i++) {
        if (closest === 0) {
            closest = arr[i]
        } else if (arr[i] &gt; 0 &amp;&amp; arr[i] &lt;= Math.abs(closest)) {
            closest = arr[i]
        } else if (arr[i] &lt; 0 &amp;&amp; -arr[i] &lt; Math.abs(closest)) {
            closest = arr[i]
        }
    }
    return closest
}


Using Array.reduce this can be written more concisely as

function calculateClosestTo0 (arr) {
    return arr.reduce((acc, x) =&gt;
        acc === 0 ? x :
        x &gt; 0 &amp;&amp; x &lt;= Math.abs(acc) ? x :
        x &lt; 0 &amp;&amp; -x &lt; Math.abs(acc) ? x : acc
    , 0)
}


Unit tests

The first versions of my suggested code had bugs as well: It “looked”
simple and correct, but returned a wrong result in special cases.
It is a good idea to collect those (and similar) cases, as well as
other special cases that you think of, into a list. Then each iteration 
of the code can be tested against that list, to ensure that it does
not introduce new bugs.

Here is the list that I came up with, it should cover many of the
possible situations:



function calculateClosestTo0 (arr) {
    return arr.reduce((acc, x) =&gt;
        acc === 0 ? x :
        x &gt; 0 &amp;&amp; x &lt;= Math.abs(acc) ? x :
        x &lt; 0 &amp;&amp; -x &lt; Math.abs(acc) ? x : acc
    , 0)
}

let tests = [
    // Single element:
    { array: [5], result: 5 },
    { array: [-5], result: -5},
    // Positive element is closer to zero:
    { array: [-3, 2], result: 2 },
    { array: [1, -2, 3, -4], result: 1 },
    // Negative element is closer to zero:
    { array: [-2, 3], result: -2 },
    { array: [-1, 2, -3, 4], result: -1 },
    // Two elements with same distance but opposite sign:
    { array: [1, -1], result: 1},
    { array: [-1, 1], result: 1},
    { array: [0, 1, -1], result: 1},
    { array: [1, 0, -1], result: 1},
    { array: [1, -1, 0], result: 1},
    { array: [0, -1, 1], result: 1},
    { array: [-1, 0, 1], result: 1},
    { array: [-1, 1, 0], result: 1},
    // Only elements of same sign:
    { array: [4, 2, 3], result: 2},
    { array: [-4, -2, -3], result: -2},
    // Empty array, or only zeros:
    { array: [], result: 0},
    { array: [0, 0, 0, 0], result: 0},
    // Closest element is at front, medium, or tail position:
    { array: [2, 0, -2, 0, -3], result: 2},
    { array: [-2, 0, 2, 0, -3], result: 2},
    { array: [-2, 0, -3, 0, 2], result: 2}
]

for (let i = 0; i &lt; tests.length; i++) {
    console.log(calculateClosestTo0(tests[i].array) == tests[i].result)
}