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