如何在嵌套数组javascript中找到最近的元素?

Sye*_*yed 2 javascript arrays ecmascript-6

假设我有一个对象数组,例如

let strokeArray = [
    {
        id:1234,
        data: [
            [101,122],
            [105,124],
            [107,127],
            [109,129],
        ]
    },
    {
        id:5678,
        data: [
            [201,522],
            [205,524],
            [207,527],
            [209,529],
        ]
    },
    {
        id:0001,
        data: [
            [601,622],
            [205,595],
            [607,627],
            [609,629],
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

我有很多要点[x,y]要说[202,523]。这个需要和数据对比

我想找到strokeArray中的哪个数组元素包含最接近上述点的值。

在上述情况下,答案是 strokeArray[1] 因为它具有数据中最近的坐标。

我还需要一些边界条件来搜索。

  • 例如,该点[300,600]应该返回空,因为它离任何数据都不远。
  • 如果找到完全匹配,我们需要该实​​例,例如[205,595]必须返回strokeArray[2]。因为它有精确匹配。

我试过的是

strokeArray.forEach((stroke) => {
      stroke.data.forEach((coordinate, index) => {
        if(coordinate === [205,595]){return index}
        // But this only checks exach match
      });
});
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我实现这一目标。

Gre*_*edo 7

这是一个简单的点对点距离计算。

背后的数学是

d = sqrt(A^2 + B^2) 其中d 是点 A 和点 B 之间笛卡尔空间上的距离。

在 2D 地方的情况下,A( xA , yA ) 和 B( xB , yB ) 论坛变为:

d = sqrt((xA-XB)^2 + (yA-yB)^2)

对于这句话,因为它远不及任何数据,我添加了一个可配置的阈值逻辑,以便您可以丢弃比某个值更远的点。

let strokeArray = [
    {
        id:1234,
        data: [
            [101,122],
            [105,124],
            [107,127],
            [109,129],
        ]
    },
    {
        id:5678,
        data: [
            [201,522],
            [205,524],
            [207,527],
            [209,529],
        ]
    },
    {
        id:0001,
        data: [
            [601,622],
            [205,595],
            [607,627],
            [609,629],
        ]
    }
];

function calcDistance(a,b){
  return Math.sqrt(Math.pow(a[0]-b[0], 2) + Math.pow(a[1]-b[1],2));
}

function nearestStroke(strokeArray, point, threshold){
  var minDistances = strokeArray.map((stroke, index) => {
    var distances = stroke.data.map((coordinate) => calcDistance(coordinate, point));
    return Math.min.apply(this, distances);
    });
  var min = Math.min.apply(this, minDistances);
  return min < threshold ? strokeArray[minDistances.indexOf(min)] : null;  
}

console.log(nearestStroke(strokeArray, [105,122], 100))
Run Code Online (Sandbox Code Playgroud)