Sorting 按地理位置剔除可观测阵列排序。

Sorting 按地理位置剔除可观测阵列排序。,sorting,knockout.js,geopoints,knockout-sortable,Sorting,Knockout.js,Geopoints,Knockout Sortable,我试图根据用户位置的接近程度,使用地理点对一个敲除可观测阵列进行排序。我有一个函数,可以循环遍历数组中的所有存储,并找到与用户当前位置最近的标记。然后我将它嵌套在另一个循环中,使用插入排序对所有元素进行排序 我有两个问题。第一。我的交换方法有点古怪。我认为它打破了dom。我想我不知道如何在一个淘汰观测中正确地交换元素 第二。这是正确的方法吗?Ko observable array有一个内置的排序方法,但我不知道如何使用最接近用户函数的点来实现它。我把代码附在下面。如有任何帮助或见解,将不胜感激

我试图根据用户位置的接近程度,使用地理点对一个敲除可观测阵列进行排序。我有一个函数,可以循环遍历数组中的所有存储,并找到与用户当前位置最近的标记。然后我将它嵌套在另一个循环中,使用插入排序对所有元素进行排序

我有两个问题。第一。我的交换方法有点古怪。我认为它打破了dom。我想我不知道如何在一个淘汰观测中正确地交换元素

第二。这是正确的方法吗?Ko observable array有一个内置的排序方法,但我不知道如何使用最接近用户函数的点来实现它。我把代码附在下面。如有任何帮助或见解,将不胜感激

var stores=ko.observearray();
storesRepository.getFeed(stores)

功能关闭标记器(lat、lng)
{

var pi=Math.pi;
var R=6371;//赤道半径
var lat1=lat;
var lon1=液化天然气;
变量距离,最近值,最小值,chLat,chLon,dLat,dLon,rLat1,rLat2,a,c,d;
对于(j=0;j
有几点:

在对可观测阵列执行大量操作时,最好在底层阵列上执行这些操作,然后在完成操作时向可观测阵列发送信号。这将减少阵列上的客户流失

以下是遵循上述规则的“更好”掉期实施:

function swap(a, b) {
    var ary = stores(),
        temp = ary[a];

    stores.valueWillMutate();
    ary[a] = ary[b];
    ary[b] = temp;
    stores.valueHasMutated();
}
既然我已经说过了,您不应该使用它:)您应该尝试使用内置的
sort
函数,而不是使用插入排序。这更好地遵循了第一条规则,只在排序操作完成后发送通知,而不是在每次交换时发送通知。内置排序使用本机浏览器代码,可能比您编写的JavaScript代码更快。您只需编写一个比较函数,指示a或b是否更接近用户,然后将其传递给排序方法:

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);
var distanceToUser=函数(a){
var lat2=a.纬度(),
lon2=a.经度(),
chLat=lat2-lat1,
chLon=lon2-lon1,
dLat=chLat*pi/180,
dLon=chLon*pi/180,
rLat1=lat1*pi/180,
rLat2=lat2*pi/180,
aa=数学单体(dLat/2)*数学单体(dLat/2)+
数学单(dLon/2)*数学单(dLon/2)*
数学cos(rLat1)*数学cos(rLat2),
c=2*Math.atan2(Math.sqrt(aa),Math.sqrt(1-aa));
返回R*c;
},
比较=功能(a,b){
var da=距离传感器(a),
db=测距器(b);
返回dadb-1:0);
};
存储。排序(比较);

如果
存储
数组中有大量的项目,则可以通过在数组中循环一次来计算到用户的距离,并将其存储为数组中每个项目的属性,然后更改
比较
方法以仅比较此距离属性来加快速度。这将防止不断重复计算距离。

太好了!因此,您将一个函数作为参数传递给sort方法,该方法接受2个参数并确定数组的排序方式。。仍然不能完全确定底层排序函数是如何工作的,但它似乎工作得很好!谢谢它使用内置的
数组。sort
。该API与您在各种语言中找到的任何其他数组排序API基本相同。这将是专门用于
数组的有用读物。排序
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);