0

I have an array of objects that contain some address data including latitude and longitude.

I have a function that calculates the distance between two sets of lat/long coordinates.

I need to sort my array from closest to farthest from a specific set of lat/long.

I'm trying to use arr.sort(comparefunction) but no luck so far. Is it possible to use an external function inside my compare function to do it?

Here is the code I tried.

function getDistance (lat1, lon1, lat2, lon2, unit) {
    var radlat1 = Math.PI * lat1/180
    var radlat2 = Math.PI * lat2/180
    var theta = lon1-lon2
    var radtheta = Math.PI * theta/180
    var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
    if (dist > 1) {
        dist = 1;
    }
    dist = Math.acos(dist)
    dist = dist * 180/Math.PI
    dist = dist * 60 * 1.1515
    if (unit=="K") { dist = dist * 1.609344 }
    if (unit=="N") { dist = dist * 0.8684 }
    return dist
}


let distributors = [
    {
        city: "A",
        lat: 44.3384925,
        long: -59.6993207,
        name: "Name 1",
    },
    {
        city: "B",
        lat: 44.3384925,
        long: -78.6993207,
        name: "Name 2",
    },
    {
        city: "C",
        lat: 64.3384925,
        long: -39.6993207,
        name: "Name 3",
    }
];

let sortedDist = distributors.sort(function(a, b){ 

    if(getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K") < getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K")){
        return -1;
    }
    if(getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K") > getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K")){
        return 1;
    }
    return 0;
})


So in this scenario, the second element in the array is the closest in distance from 44.3617171302915, -79.65860486970848, but I console.log(sortedDist) and nothing has changed.

2
  • 4
    Do you note both results of getDistance() are the same inside the same if setence? Note you are always using a.lat and a.long and never b.lat or b.lang. So the sort comparison method is always returning 0. Commented Apr 30, 2019 at 18:27
  • If you've got lots of those points (hundreds or more) you could probably speed up the sort by making a single linear pass over the list computing the distance for each point and saving it on each object. That would result in a significantly smaller number of calls to getDistance(). Commented Apr 30, 2019 at 18:55

1 Answer 1

3

The problem is that you're comparing a against a, try:

let sortedDist = distributors.sort(function(a, b){ 

    if(getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K") < getDistance(44.3617171302915, -79.65860486970848, b.lat, b.long, "K")){
        return -1;
    }
    if(getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K") > getDistance(44.3617171302915, -79.65860486970848, b.lat, b.long, "K")){
        return 1;
    }
    return 0;
})

or the same with shorter syntax:

let sortedDist = distributors.sort(function(a, b){ 

    let aDist = getDistance(44.3617171302915, -79.65860486970848, a.lat, a.long, "K");
    let bDist = getDistance(44.3617171302915, -79.65860486970848, b.lat, b.long, "K");

    return aDist - bDist;
})
Sign up to request clarification or add additional context in comments.

2 Comments

You can shorten it even further by: return aDist - bDist
My bad, I had the wrong logic before (when I had fixed this repeated a issue) and then when i wrote the correct logic I made the same mistake again. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.