我有两个数组:
var element_1 = new Array([x1,y1],[x2,y2],[x3,y3],[x4,y4]);
var element_2 = new Array([x1,y1],[x2,y2],[x3,y3],[x4,y4]);
逻辑:
我想运行一个循环(嵌套),其中element_1
的每个元素(例如[x1,y1]
)与element_2
的每个元素和最短距离之间进行比较它们应该在循环内计算(我知道如何计算最短路径)。这里棘手的部分是我需要一个参考,哪一对最短,然后获得那些[x1,y1]
和[x2,y2]
组合来绘制一条线。
示例数据:
var element_1 = new Array([10,0],[20,10],[10,20],[0,10]);
var element_2 = new Array([10,30],[20,40],[10,50],[0,40]);
线应在[10,20]和[10,30]之间。此外,我会以某种方式将坐标存储在某处以将其传递给线条绘制函数
我该怎么做?任何线索都将受到高度赞赏。
答案 0 :(得分:3)
我将如何做到这一点:
var element_1 = [[0,0],[1,2],[5,3],[6,8]];
var element_2 = [[0,1],[1,4],[5,9],[9,8]];
var closest = {a: false, b: false, distance: false};
for(var i=0; i<element_1.length; i++) {
for(var j=0; j<element_2.length; j++) {
var distance = calculate_distance(element_1[i], element_2[j]);
console.log('Distance between element_1['+i+'] and element_2['+j+']: ' + distance);
if(closest.distance === false || distance < closest.distance) {
closest = {a: element_1[i], b: element_2[j], distance: distance};
}
}
}
console.log('The shortest path is between '+closest.a+' and '+closest.b+', which is '+closest.distance);
function calculate_distance(a, b) {
var width = Math.abs( a[0] - b[0] ),
height = Math.abs( a[1] - b[1] ),
hypothenuse = Math.sqrt( width*width + height*height );
return hypothenuse;
}
&#13;
正如Roko C. Buljan所述,在您的情况下,您可以将new Array()
替换为[]
。 Here's why 的
答案 1 :(得分:1)
我很喜欢这个问题。它激发了我发明一种通用的Array方法,以便对两个数组的其他项应用回调。所以我称之为Array.prototype.withEachOther()
。它的作用正是@blex在其嵌套for循环的解决方案中所做的。它将一个操作(由回调提供)应用于每个数组项与另一个数组的项。让我们看看它是如何运作的。
Array.prototype.withEachOther = function(a,cb,s=0){
return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);
};
var element_1 = [[10,0],[20,10],[10,20],[0,10]],
element_2 = [[10,30],[20,40],[10,50],[0,40]],
cb = (p1,p2,q) => {var h = Math.hypot(p1[0]-p2[0],p1[1]-p2[1]);
return h < q.d ? {d:h,p1:p1,p2:p2} : q},
minDist = element_1.withEachOther(element_2,cb,{d:Number.MAX_SAFE_INTEGER,p1:[],p2:[]});
console.log(minDist);
让我们来解释发生了什么。
Array.prototype.withEachOther = function(a,cb,s=0){
return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);
};
是一个可重用的功能。它将执行回调函数中提供的操作,与两个数组中的每个其他元素一起执行。它需要3个参数(a,cb,s=0)
。
a
是第二个数组,我们将回调函数应用于调用.withEachOther
的数组的每个项目。cb
是回调。下面我将解释针对此问题应用的回调。s=0
是我们将开始的初始值(默认值为0)。它可以是任何取决于回调函数的东西。 return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);
这部分是该功能的核心。如你所见它有两个嵌套减少。外部reduce具有由s
指定的初始值,其如上所述提供。初始值最初被分配给外部reduce的回调的p
参数,而另一个参数et
被逐个分配给每个调用数组的项。 ( e 借用 t 他的)。在外部reduce中我们调用另一个reduce(内部reduce)。内部reduce从前一个循环的结果的初始值开始,该值是外部reduce的p
,并且在每次计算之后将结果返回到它的减少值变量q
。 q
是我们的记忆,并在回调中进行测试,看看我们是保持原样还是用我们的计算结果替换它。在内部reduce完成一轮完成之后,它将返回q
到p
,同样的机制将再次运行,直到我们完成调用.withEachOther
的数组的所有项。
cb = (p1,p2,q) => {var h = Math.hypot(p1[0]-p2[0],p1[1]-p2[1]);
return h < q.d ? {d:h,p1:p1,p2:p2} : q}
回调是这个问题的特殊之处。它将接收两个点(每个点都有x和y坐标)将计算它们之间的距离,并将其与先前进行的计算进行比较。如果它更小,它将通过返回此新值来替换q
;如果不是,它将原样返回q
。