javascript / jquery - finding the closest value in an array

Go To StackoverFlow.com

0

I'm modifying the jquery ui slider. I have certain "stops" I want the user to be able to slide to, expressed as a percentage of the slider's overall width. So, for example, if I have 3 stops, they will be distributed evenly at 0, 50, and 100 (%). I store these in an array [0,50,100].

When the user drags the slider and releases, I capture the slider's current value. So if he scrolled 56% of the way across the bar, his stopVal is 56.

How do I write a function that will then determine which number in the array this stopVal is closest to? Here's my code:

var optValArr = [0,50,100];

function slideStop( event, ui ) {
    var stopVal = ui.value;
    //NOW NEED TO FIND CLOSEST ARRAY VALUE TO stopVal   
}
2012-04-05 00:04
by mheavers


3

Try This:

var optValArr = [0,50,100];

function slideStop( event, ui ) {
    var stopVal = ui.value;
    var diff=101;
    var val =0;

    for(var i =0; i < optValArr.length; i++){
        var tmpDiff = Math.abs(stopVal - optValArr[i]);
        if(tmpDiff < diff){
           diff=tmpDiff;
           val = optValArr[i]
        }
    }             
}
slideStop("something", {"value":20});

Demo: http://jsfiddle.net/ggzZj/

2012-04-05 00:17
by Kevin Bowersox
That's great, thanks for the help - mheavers 2012-04-05 12:35
@mheavers anytime glad i could hel - Kevin Bowersox 2012-04-05 12:38


4

This function will let you do that:

Array.prototype.closest = function(value) {
   var i;

   function diff(n) {
      var diff = n - value;

      return diff < 0 ? -diff : diff;
   }

   var found = this[0],
       mindiff = diff(found);

   for (i = 1 ; i < this.length ; i++) {
      var currentdiff = diff(this[i]);

      if (currentdiff < mindiff) {
          found = this[i];
          mindiff = diff(found);
      }
   }

  return found;
}

Now you can do this:

var optValArr = [0,50,100];

function slideStop( event, ui ) {
    var stopVal = ui.value;
    //NOW NEED TO FIND CLOSEST ARRAY VALUE TO stopVal 


   stopVal = optValArr.closest(stopVal);
}

NOTE: Some people consider defining prototypes for native types as dangerous as it can cause conflicts if two libraries do the same (just like global variable). If you are writing a public library you should therefore avoid adding to the prototypes of native types.

2012-04-05 00:18
by d_inevitable
Please give reasons for downvotes. I'd be happy to improve on my answer, if given a chance - d_inevitable 2012-04-05 00:36
Your adding enumerable properties to a native prototype without warning about the side effect - Raynos 2012-04-05 13:04
Ok, thx. I have updated my answer - d_inevitable 2012-04-05 15:39
It's dangerous because it messes up for loops as wel - Raynos 2012-04-05 15:40
Well I would say its dangerous to loop them in that case, but you do have a point - d_inevitable 2012-04-05 16:01


1

var optValArr = [0,50,100];

function slideStop( event, ui ) {
    var stopVal = ui.value;
    var closestVal = optValArr.reduce(function (memo, curr) {
        var currDiff = Math.abs(curr - stopVal),
            memoDiff = Math.abs(memo - stopVal)

        return memoDiff < currDiff ? memoDiff : currDif
    }) 
}
2012-04-05 00:28
by Raynos
Is reduce supported < IE9 - Kevin Bowersox 2012-04-05 09:46
This is great. Unfortunately kmb385 has a point, reduce won't really work for my purposes due to browser support - https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce. Thanks though - it's good to know this function is out there - mheavers 2012-04-05 12:30


0

Another common definition of "closer" is based on the square of the difference. But, you could do that by simply adding the number that you want in your original array like this:

[10,40,50, my_number]

Then, sort your array and then you choice if you want the closest position from the right or the left.

What do you think?

2012-04-05 00:23
by Igor Escobar
Ads