A couple of points:
When performing lots of manipulations on an observable array, it is best to perform them on the underlying array, then signal the observable array when you are done. This will reduce churn on the array.
Here is a "better" implementation of swap which follows the above rule:
function swap(a, b) {
var ary = stores(),
temp = ary[a];
stores.valueWillMutate();
ary[a] = ary[b];
ary[b] = temp;
stores.valueHasMutated();
}
Now that I've said that, you should not use it :) You should instead try to use the built-in sort
function instead of using your insertion sort. This follows the first rule even better by only sending out a notification once the sort operation is complete, instead of on every swap. And the built in sort uses native browser code and will likely be faster than JavaScript code you write. All you need to do is write a comparison function which indicates whether a or b is closer to the user, then pass it to the sort method:
var distanceToUser = function (a) {
var lat2 = a.latitude(),
lon2 = a.longitude(),
chLat = lat2 - lat1,
chLon = lon2 - lon1,
dLat = chLat * pi / 180,
dLon = chLon * pi / 180,
rLat1 = lat1 * pi / 180,
rLat2 = lat2 * pi / 180,
aa = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) *
Math.cos(rLat1) * Math.cos(rLat2),
c = 2 * Math.atan2(Math.sqrt(aa), Math.sqrt(1 - aa));
return R * c;
},
compare = function (a, b) {
var da = distanceToUser(a),
db = distanceToUser(b);
return da < db ? -1 : (da > db ? 1 : 0);
};
stores.sort(compare);
If you have a very large number of items in your stores
array, then this could be sped up by looping through the array once to calculate the distance to the user and storing it as a property on each item in the array, then changing the compare
method to just compare this distance property. That would prevent continually recalculating the distance over and over.