用于绘制线javascript的循环逻辑

时间:2016-06-09 20:26:22

标签: javascript arrays loops

我有两个数组:

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]之间。此外,我会以某种方式将坐标存储在某处以将其传递给线条绘制函数

我该怎么做?任何线索都将受到高度赞赏。

2 个答案:

答案 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;
&#13;
&#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,并且在每次计算之后将结果返回到它的减少值变量qq是我们的记忆,并在回调中进行测试,看看我们是保持原样还是用我们的计算结果替换它。在内部reduce完成一轮完成之后,它将返回qp,同样的机制将再次运行,直到我们完成调用.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