Contact!

Find the closest number in an array JavaScript

Find nearest number in array

Today I was making a ‘draggy’, ‘slidey’, web component, control, ‘thing’ which needed to snap to pre-determined positions when the drag ended. This meant that I had to find the closest number in an array to where my drag ended and animate a snap to that position.

This funny little problem seems to be a bit polarising because there are a few solutions you could roll with. In the end I decided to use reduce() mainly because it was my initial instinct, but also because it isn’t every day that you find an actual ‘use for reduce()’!

Find the closest value in array using reduce()

So how do you find the closest value in an array using reduce()?

First we need to know how to get the difference between 2 numbers in JavaScript. The easiest way to do this is to use Math.abs(), so lets use that.

Second we need a function to compare each value of an array and return the closest to our ‘needle’. This is where reduce() comes in. Reduce will run a callback function on each element in an array and then return the result of the last callback invocation. Lets have a look:

const needle = 8;

const closest = [1, 10, 7, 2, 4].reduce((a, b) => {
    return Math.abs(b - needle) < Math.abs(a - needle) ? b : a;
});

console.log(closest); // Output: 7

With this function we check whether the absolute value of (b – 8) is less than the absolute value of (a – 8) and then return the winner. ‘a’ becomes the winner and is then checked against the next value in the array. We do this until every value has been evaluated, returning 7 in the last invocation.

The main issue with this approach is that it will return the first ‘nearest’ number it comes across. If we were to push 9 to the end of the array then 7 would still be returned because it is the first ‘nearest’ value to be evaluated.

Obviously this can matter, and if it does to you then it should be checked for in our reduce function.

const needle = 8;

const closest = [1, 10, 7, 2, 4, 9].reduce((a, b) => {
    let aDiff = Math.abs(a - needle);
    let bDiff = Math.abs(b - needle);

    if (aDiff == bDiff) {
        // Choose largest vs smallest (> vs <)
        return a > b ? a : b;
    } else {
        return bDiff < aDiff ? b : a;
    }
});

console.log(closest);

In this example we are returning the largest number. To make this return the smallest number we simply change ‘a > b ? a : b’ to ‘a < b ? a : b’.

If we want to turn this into a reusable function then we could do something like this:

function closest(needle, haystack) {
    return haystack.reduce((a, b) => {
        let aDiff = Math.abs(a - needle);
        let bDiff = Math.abs(b - needle);

        if (aDiff == bDiff) {
            return a > b ? a : b;
        } else {
            return bDiff < aDiff ? b : a;
        }
    });
}

Find the closest value in array using sort()

Another approach is to sort() the array by closest absolute value to our ‘needle’. This would mean that position [0] of our array is now the closest match.

const needle = 8;
const numbers = [1, 10, 7, 2, 4, 9];

numbers.sort((a, b) => {
    return Math.abs(needle - a) - Math.abs(needle - b);
})

console.log(numbers[0]);

I don’t like this approach as much because the previous solution feels ‘neater’ as the reducer returns a single value… reduce() actually executes faster, too!

  1. SEO Company says:

    Awesome post! Keep up the great work! 🙂

  2. AffiliateLabz says:

    Great content! Super high-quality! Keep it up! 🙂

  3. Nischith says:

    Can you please update on using array of Objects ?

    1. Brian says:

      Hi Nischith,

      I believe in reduce(a, b)… the ‘a’ and ‘b’ ref the element or object in an array.

      So if you had an array of objects instead of numbers ‘a’ and ‘b’ would ref the object in the array.

      To ref a property in the object within your array you would use a.property and b.property in your code replacing ‘property’ with your actual key in your object.

      You could do this also if it makes more sense…

      arr.reduce(obj1, obj2 => {
      obj1.yourObjectKey obj2.yourObjectKey
      })

      (obj1, obj2) are the same as (a, b)

  4. pedi says:

    man you just saved my day…
    I’ve been stuck at this for 2 days

  5. Montserrat says:

    this is awesome, you made me want to learn what I’ve been avoiding during a whole semester, thank you!

  6. Brian says:

    Great post! This really saved me lots of mental energy and time!! I ended up using the .sort() because I needed the 10 closets values to a number.

    const allComps = soldsWithForSales
    .filter(prop => prop.result === true)
    .sort((a, b) => {
    // sorts all comps is order closest subject valuation
    return Math.abs(subVal – a.price) – Math.abs(subVal – b.price);
    });

    const topTen = allComps.slice(0, 10);

  7. matteo says:

    This is exactly what I was looking for, props!

  8. jaymangal says:

    great

  9. David Momoh says:

    Thank you for the great content sir. I want to ask, What if the needle parameter is also an array. How then do you do it?

  10. Dryden says:

    Great post! I wondered how you would extend closest to match the closest object in an array to some fixed values e.g.

    “`
    const needleValues = {
    a: 0,
    b: 3,
    c: 7,
    d: 2
    }

    const items = [
    {
    // This first one should match
    a: 0,
    b: 3,
    c: 7,
    d: 2
    },
    {
    a: 2,
    b: 5,
    c: 2,
    d: 8
    },
    {
    a: 1,
    b: 7,
    c: 2,
    d: 9
    }
    ]
    “`

    Thanks 🙂

Join the discussion!

You might like:

Create, register and use shortcodes in WordPress

Create, register and use shortcodes in WordPress

by Gav 18/03/2023

Learn how to create and register your own WordPress shortcodes to add dynamic content to your posts and pages.

How to use guard clauses in JavaScript

How to/why use guard clauses in JavaScript

by Gav 16/03/2023

Learn how to improve code readability and performance by using guard clauses in JavaScript. Discover their benefits and best practices.

Implements and Extends, Object Oriented TypeScript

Implements and Extends, Object Oriented TypeScript

by Gav 15/03/2023

Learn the difference between implements and extends in TypeScript. Use Implements to implement interfaces and types, and extends to inherit from classes.

Reading/Parsing and Writing YAML files in PHP, Symfony

Reading/Parsing and Writing YAML files, PHP Symfony

by Gav 14/03/2023

In this tutorial we will look at using YAML in PHP. Learn about Parsing and Writing YAML files using Symfony's YAML component.

Measuring code execution performance in JavaScript

Measuring code execution performance in JavaScript

by Gav 13/03/2023

Measuring code execution performance is an important way to identify bottlenecks. Use these methods in JavaScript to help optimise your code.

Measuring script/code execution time in PHP using microtime

Measuring script/code execution time in PHP, microtime

by Gav 06/03/2023

Find bottlenecks, optimise and clean your code, and speed up your apps by measuring the execution time of your PHP scripts using microtime.

Regenerate WordPress media image sizes, programmatically

Regenerate WordPress media image sizes, programmatically

by Gav 25/02/2021

Learn how to regenerate and update WordPress media and image sizes both programmatically (without plugin), and also with a handy plugin.

Magic Constants in PHP. What they are and how to use them.

Magic Constants in PHP. What they are and how to use them

by Gav 15/02/2021

Ever seen constants like __DIR__ and __FILE__ being used in PHP? These are 'Magic Constants', and this is how we can use them.

Detecting Keypress JavaScript

Detect single and multiple keypress events: JavaScript

by Gav 16/10/2019

Learn how to use event listeners to detect and handle single and multiple keypress events in JavaScript. Add modifier keys to your application!