JavaScript: Find the number in an array which is closest to an given number It's actually an exercise from an Assembly-course I'm doing:


  Find closest number.

Add the following into the data section:

nums  dd  23h,75h,111h,0abch,443h,1000h,5h,2213h,433a34h,0deadbeafh

This is an array of numbers. 

Write a program that receives a number x as input, and finds the dword
inside the array nums, which is the closest to x. (We define the distance
between two numbers to be the absolute value of the difference: |a-b|).

Example:

For the input of 100h, the result will be 111h, because 111h is closer to
100h than any other number in the nums array. (|100h - 111h| = 11h).



Full exercise-sheet on GitHub.

Because it's easier for me to develop the algorithm in more familiar JavaScript and because it's a nice exercise I have done it in JavaScript first. Now the only thing left to do is to find an Assembly-specific way. 

Anyway: Here's the JavaScript-code I've written to solve the task.



let nums = [ 0x23, 0x75, 0x111,
             0xabc, 0x443, 0x1000,
             0x5, 0x2213, 0x433a34,
             0xdeadbeaf
           ];
let given = 0x100; // { 256 }10

// --- The Relevant Part --------------------------------------
function findIndexClosestNumber(arrayToSearch, compareNumber) {
  'use strict';
  let closest = compareNumber;
  let indexClosest = 0;

  arrayToSearch.forEach((currentNumber, index) =&gt; {
    let currentDistance =
      Math.abs(compareNumber - currentNumber);

    if (currentDistance &lt; closest) {
      indexClosest = index;
      closest = currentDistance;
    }
  });

  return indexClosest;
}
// -------------------------------------------------------------

// ------ Testing &amp; Demo ---------------------------------------
console.log(findIndexClosestNumber(nums, given));

nums.length = 0;

for (let i = 0; i &lt;= 90; i += 10) {
  nums.push(i);
}

console.log(nums);

for (let i = 0; i &lt; 10; i++) {
  var randomNumber = Math.floor((Math.random() * 100));

  console.log('%s gives index %s', randomNumber,
    findIndexClosestNumber(
      nums, randomNumber));
}





Can I expect my implementation to solve the task in a correct way?
Was it a good idea to initialize the closest-variable with the value of the compareNumber-parameter?
Was it a good idea to check for currentDistance &lt; closest? Or should I have used currentDistance &lt;= closest?


Currently the first occurrence-index is returned in case the number is contained multiple times. Using &lt;= it would return the last occurrence-index. 

I'm not sure what's the better practice.

Any other comments concerning structure, naming, used methods, algorithm appreciated too.

And if someone knows a cool JavaScript specific way to solve the task: That would interest me too. ;)
Your main questions


  
  Can I expect my implementation to solve the task in a correct way?
  


You should know that the answer is "yes" before posting a question on Code Review.


  
  Was it a good idea to initialize the 'closest'-variable with the value of the 'compareNumber'-parameter?
  


No, it's a mistake. The function incorrectly returns 0 for input [10, 9], 3.
When looking for the minimum distance,
you must choose as the default the largest possible number.
For example if you target ES6, then Number.MAX_SAFE_INTEGER.


  
  Was it a good idea to check for 'currentDistance &lt; closest'? Or should I have used 'currentDistance &lt;= closest'?
  


That depends entirely on the specification.
If you're looking for the first closest index, then use &lt;.
If the last, then use &gt;.

If the specification was not clear,
then ask to clarify.

Naming

The names are overly verbose.
When short names are sufficient, they are better than long names.

For example,
in a function to find the closest index to a number,
the array parameter is obviously for searching,
so instead of arrayToSearch, it could be simply nums,
and compareNumber could be target.

I would have written like this:

function indexOfClosest(nums, target) {
  let closest = Number.MAX_SAFE_INTEGER;
  let index = 0;

  nums.forEach((num, i) =&gt; {
    let dist = Math.abs(target - num);

    if (dist &lt; closest) {
      index = i;
      closest = dist;
    }
  });

  return index;
}