Javascript 在数组中查找连续的匹配位置
我有一个位置数组,希望找到与第一个位置不同的第一个位置(或一组位置)。我所说的“不同”是指基于确定其距离的函数的明显不同的位置。下面是一个示例阵列:Javascript 在数组中查找连续的匹配位置,javascript,arrays,Javascript,Arrays,我有一个位置数组,希望找到与第一个位置不同的第一个位置(或一组位置)。我所说的“不同”是指基于确定其距离的函数的明显不同的位置。下面是一个示例阵列: [ {lat: 45, lng: 45}, // 1st Location {lat: 45.01, lng: 45.01}, // 1st Location {lat: 55, lng: 55}, // 2nd Location - MATCH {lat: 55.01, lng: 5
[
{lat: 45, lng: 45}, // 1st Location
{lat: 45.01, lng: 45.01}, // 1st Location
{lat: 55, lng: 55}, // 2nd Location - MATCH
{lat: 55.01, lng: 55.01}, // 2nd Location - MATCH
{lat: 54.99, lng: 54.99}, // 2nd Location - MATCH
{lat: 55, lng: 55}, // 2nd Location - MATCH
{lat: 65, lng: 65}, // 3rd Location
{lat: 65.01, lng: 65.01} // 3rd Location
]
在上面的示例中,结果应该是仅包含第二个位置的数组。如果位置在0.2 lat/lng范围内,则假设位置匹配
我目前的解决办法是:
var位置=[
{lat:45,lng:45},
{lat:45.01,lng:45.01},
{lat:55,lng:55},
{lat:55.01,lng:55.01},
{lat:54.99,lng:54.99},
{lat:55,lng:55},
{lat:65,lng:65},
{lat:65.01,lng:65.01}
];
常数起始位置=位置。拼接(0,1)[0];
const first=locations.findIndex(location=>{
const{lat,lng}=位置;
返回新位置(startingLocation.lat,startingLocation.lng,lat,lng);
});
const validLocations=locations.slice(第一个);
const newLatLng=有效位置[0];
const last=validLocations.findIndex(位置=>{
const{lat,lng}=位置;
返回新地点(newLatLng.lat,newLatLng.lng,lat,lng);
});
如果(上次>-1){
有效位置。拼接(最后);
}
控制台日志(有效位置)
//用于测试位置是否相同的Helper函数
//仅供演示之用
函数新位置(lat1、lng1、lat2、lng2){
返回Math.abs(lat1-lat2)+Math.abs(lng1-lng2)>1
}
您的双循环解决方案简单、直接且高效。没有理由改变这一切。但是,您不应该太频繁地对任何数组进行切片
和拼接
,在初始数组中找到匹配项的第一个和最后一个索引就足够了,然后在最后进行一次切片
此外,您的代码可以简化很多:
const firstMatch = findIndexFrom(locations, differentTo(locations[0]), 1);
if (firstMatch == -1) return [];
const afterMatch = findIndexFrom(locations, differentTo(locations[firstMatch]), firstMatch+1);
if (afterMatch == -1) return locations.slice(firstMatch);
else return locations.slice(firstMatch, afterMatch);
function differentTo(target) {
return function(location) {
return Math.abs(target.lat - location.lat) + Math.abs(target.lng - location.lng) > 1;
};
}
function findIndexFrom(arr, pred, index) { // unfortunately the native `findIndex` doesn't take a start position like `indexOf`
for (; index < arr.length; index++)
if (pred(arr[index], index))
return index;
return -1;
}
const firstMatch=findIndexFrom(位置,差分到(位置[0]),1);
if(firstMatch==-1)返回[];
const afterMatch=findIndexFrom(位置,差异到(位置[firstMatch]),firstMatch+1);
if(afterMatch==-1)返回locations.slice(firstMatch);
否则返回位置。切片(firstMatch,afterMatch);
功能差异(目标){
返回函数(位置){
返回Math.abs(target.lat-location.lat)+Math.abs(target.lng-location.lng)>1;
};
}
函数findIndexFrom(arr,pred,index){//不幸的是,本机的'findIndex'没有像'indexOf'那样的起始位置`
对于(;索引
您的双循环解决方案简单、直接且高效。没有理由改变这一切。但是,您不应该太频繁地对任何数组进行切片
和拼接
,在初始数组中找到匹配项的第一个和最后一个索引就足够了,然后在最后进行一次切片
此外,您的代码可以简化很多:
const firstMatch = findIndexFrom(locations, differentTo(locations[0]), 1);
if (firstMatch == -1) return [];
const afterMatch = findIndexFrom(locations, differentTo(locations[firstMatch]), firstMatch+1);
if (afterMatch == -1) return locations.slice(firstMatch);
else return locations.slice(firstMatch, afterMatch);
function differentTo(target) {
return function(location) {
return Math.abs(target.lat - location.lat) + Math.abs(target.lng - location.lng) > 1;
};
}
function findIndexFrom(arr, pred, index) { // unfortunately the native `findIndex` doesn't take a start position like `indexOf`
for (; index < arr.length; index++)
if (pred(arr[index], index))
return index;
return -1;
}
const firstMatch=findIndexFrom(位置,差分到(位置[0]),1);
if(firstMatch==-1)返回[];
const afterMatch=findIndexFrom(位置,差异到(位置[firstMatch]),firstMatch+1);
if(afterMatch==-1)返回locations.slice(firstMatch);
否则返回位置。切片(firstMatch,afterMatch);
功能差异(目标){
返回函数(位置){
返回Math.abs(target.lat-location.lat)+Math.abs(target.lng-location.lng)>1;
};
}
函数findIndexFrom(arr,pred,index){//不幸的是,本机的'findIndex'没有像'indexOf'那样的起始位置`
对于(;索引
这基本上是一个问题,存在许多不同的算法。@Bergi我可以看到如何使用字符串匹配来解决它,但这似乎不是一个很好的解决方案。你能举个例子吗?哦,等等,我好像误解了你的问题。只有标题“在数组中查找连续匹配”提醒了我字符串匹配问题。明白了。我很难解释问题中的问题,这可能是因为它没有得到太多的关注。有输入吗?这基本上是一个,有许多不同的算法。@Bergi我可以看到如何使用字符串匹配来解决它,但这似乎不是一个很好的解决方案。你能举个例子吗?哦,等等,我好像误解了你的问题。只有标题“在数组中查找连续匹配”提醒了我字符串匹配问题。明白了。我很难解释问题中的问题,这可能是因为它没有得到太多的关注。有什么意见吗?