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我可以看到如何使用字符串匹配来解决它,但这似乎不是一个很好的解决方案。你能举个例子吗?哦,等等,我好像误解了你的问题。只有标题“在数组中查找连续匹配”提醒了我字符串匹配问题。明白了。我很难解释问题中的问题,这可能是因为它没有得到太多的关注。有什么意见吗?