kinzito17
kinzito17

Reputation: 300

Return Sorted Array after For Loop

I am attempting to get the distance between to lat|long coordinates by using the npm geolib. I have a function in which I query firestore and get an array of objects back. I then run that array through a for loop where I call geolib.getPreciseDistance to get the distance for each object of the array.

I am having a hard time getting a sorted array in return from the for loop. In a perfect world the new array would be sorted with the object with the closest distance in index[0].

I've posted as far as I have got below. I appreciate any and all feedback as I am still learning. Thanks!

  function getNearestWalk() {
    let currentLng = userLocation.longitude;
    let currentLat = userLocation.latitude;
    firestore()
      .collection('Walks')
      .where('status', '==', 'started')
      .limit(10)
      .get()
      .then((walks) => {
        const walksArray = [];
        walks.forEach((liveWalks) => {
          walksArray.push(liveWalks.data());
        });
        console.log(walksArray);

        for (var i = 0; i < walksArray.length; i++) {
          geolib.getPreciseDistance(
            { latitude: currentLat, longitude: currentLng },
            {
              latitude: walksArray[i].latitude,
              longitude: walksArray[i].longitude,
            }
          );
        }
      });
  }

Upvotes: 0

Views: 114

Answers (2)

danh
danh

Reputation: 62676

In the OP code, walks is a querySnapshot. The first thing to do is extract the doc data. This function does the query and gets the docs' data...

function getStartedWalks() {
  return firestore()
      .collection('Walks')
      .where('status', '==', 'started')
      .limit(10)
      .get()
      .then(querySnapshot => querySnapshot.docs.map(d => d.data()));
}

This function assigns distance from a given point into the doc data...

// to each doc in docs, assign the distance from a given position
function assignDistances(docs, position) {
  return docs.map(doc => {
    const docPosition = { latitude: doc.latitude, longitude: doc.longitude };
    const distance = geolib.getPreciseDistance(position, docPosition);
    return { ...doc, distance }
  })
}

Now getNearestWalk() is easy to write...

function getNearestWalk(position) {
  return getStartedWalks().then(docs => {
    docs = assignDistances(docs, position)
    return docs.sort((a, b) => a.distance - b.distance)
  });
}

Call it like this...

getNearestWalk(userLocation.latitude, userLocation.longitude).then(array => {
  // array will be the doc data, sorted by distance from userLocation
})

Upvotes: 1

Dan der Mensch
Dan der Mensch

Reputation: 332

From what I gathered in your response to @Elnatan, sounds like you want an array of objects representing coordinates sorted by shortest...farthest distance

The most straightforward way (without regard to complexity) is below:

  • Create a helper function distCalc that accepts an object to perform your loop logic that called geolib.getPreciseDistance and returns its value.
  • Then you can set a variable that points to the evaluation of:
    walksArray.sort( (a, b) => distCalc(a) - distCalc(b) )
  • Return your sorted array.

Personally, I would separate concerns in your #getNearestWalk for best practice and create a helper function that fetches your walks so as to implement effective error handling with try {} catch {} since asynchronous calls are not guaranteed.

Let me know if this works for you!

Upvotes: 1

Related Questions