# Loop logic for drawing line javascript

I have following two arrays:

``````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]);
``````

Logic: I want to run a loop (nested) where each element of `element_1` (for eg `[x1,y1]`) is compared to each element of `element_2` and the shortest distance between them shall be calculated within the loop (I know how to calculate the shortest path). The tricky part here is that I need a reference that which pair made the shortest past and then obtain those `[x1,y1]` and `[x2,y2]` combinations to draw a line.

Sample data:

``````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]);
``````

Line should be made between [10,20] and [10,30]. Also, I would somehow need to store the coordinates somewhere to pass it to the line drawing function

How can I do this? Any leads would be highly appreciated.

## 评论

### Here is how I would do it:

Here is how I would do it:

``````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 - b ),
height = Math.abs( a - b ),
hypothenuse = Math.sqrt( width*width + height*height );
return hypothenuse;
}``````

As Roko C. Buljan said, in your case you can just replace `new Array()` with `[]`. Here's why.

### Well i liked this question a

Well i liked this question a lot. It inspired me to invent a generic Array method to apply a callback with each other items of two arrays. So i called it `Array.prototype.withEachOther()`. What it does is exactly what @blex has done in his solution with nested for loops. It applies an operation (provided by the callback) to each array item with the other array's item. Let's see how it works.

``````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-p2,p1-p2);
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);``````

So let's explain what's going on.

``````Array.prototype.withEachOther = function(a,cb,s=0){
return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);
};
``````

is a reusable function. It will execute the operation that is provided in a callback function, with each other element of the two arrays. It takes 3 arguments `(a,cb,s=0)`.

• `a` is the second array that we will apply our callback to each item for each item of the array that is invoking `.withEachOther`.
• `cb` is the callback. Below I will explain the callback applied specific for this problem .
• `s=0` is the initial (with a default value of 0) value that we will start with. It can be anything depending on the callback function.

`return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);`

this part is the core of the function. As you see it has two nested reduces. The outer reduce has an initial value designated by the `s`, which is provided as explained above. The initial value gets initially assigned to the `p` argument of the outer reduce's callback and the other argument `et` is assigned one by one with each of the items of invoking array. (element of this). In the outer reduce we invoke another reduce (the inner reduce). The inner reduce starts with the initial value of the result of previous loop which is the `p` of outer reduce and after each calculation returns the result to it's reduced value variable `q`. `q` is our memory and tested in the callback to see if we keep it as it is or replace it with the result of our calculation. After inner reduce finishes a complete round it will return the `q` to `p` and the same mechanism will run again until we finish with all items of the array that's invoking `.withEachOther`.

``````cb = (p1,p2,q) => {var h = Math.hypot(p1-p2,p1-p2);
return h < q.d ? {d:h,p1:p1,p2:p2} : q}
``````

The callback is special to this problem. It will receive two points (each with x and y coordinates) Will calculate the distance between them and will compare it with the previously made calculation. If it's smaller it will replace `q` by returning this new value; if not it will return `q` as it is.