javascript - while 循环为世界旅行创建一个数组
问题描述
我得到了以下代码,我试图在其中输出完整行程的结果。起点在Start
,接下来的目的地将是
Start's
坐标与其余城市之一(在本例中为多伦多)之间的最短距离。
在我的calcDirectRoute
中,我只能输出Start
>> Toronto
trip 元素,因为我正在努力保持循环,其中数组的第二个元素是andTripList
之间的最短距离,比方说,依此类推,直到没有更多的城市离开去旅行。Toronto
London
在这种情况下,如何继续循环使用 while 循环?有人可以帮忙吗?
在我的示例中,以公里为单位的坐标/距离是虚构的。
const world = [
[["Start"], [20, 20]],
[["NY"], [29, 30]],
[["London"], [24, 27]],
[["Moscow"], [29, 32]],
[["Toronto"], [20, 23]]
];
const calcDist2Points = function (p2, p1) {
const r = 6371;
let d, dLat, dLon;
const lat2 = p2[1][0];
const lon2 = p2[1][1];
const lat1 = p1[1][0];
const lon1 = p1[1][1];
dLat = lat2 - lat1;
dLon = lon2 - lon1;
let a =
Math.sin(dLat / 2) ** 2 +
Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
d = r * c;
return d; // distance in km
};
const calcDirectRoute = function (input) {
let tripList = [];
let distances = [];
let tempStart = input[0];
for (let i = 1; i < input.length; i++) {
distances.push([tempStart[0], [tempStart[1][0], tempStart[1][1]], input[i][0], [input[i][1][0], input[i][1][1]], calcDist2Points(input[i], tempStart)]);
}
let short = distances[0];
for (let i = 0; i < distances.length; i++) {
for (let n = i + 1; n < distances.length; n++) {
if (distances[n][4] < short[4])
short = distances[n];
}
}
// push EACH short result to tripList array
tripList.push(short);
tempStart = short.slice(2);
return tripList;
}
console.log(calcDirectRoute(world));
解决方案
我需要更新一点你的calcDist2Points()
功能。我还更新了world
对象的定义方式。
distance 属性表示到上一个城市的距离。
我相信我可以使用第三个库进行改进以使其更简单。现在我相信是功能性的。
const formatOutput = (tripList) =>
tripList.reduce((acc, { name, coordinates, distance }, index, arr) => {
if (index <= 0) return [];
const { name: prevName, coordinates: prevCoordinates } = arr[index - 1];
const obj = [[prevName], prevCoordinates, [name], [...coordinates], distance];
return [...acc, obj];
}, []);
const compareByDistance = ({ distance: distanceA }, { distance: distanceB }) => distanceA - distanceB;
const getDistances = (origin, cities) =>
Object.entries(cities)
.map(([city, coordinates]) => ({ name: city, coordinates, distance: calcDist2Points(origin, coordinates) }))
.sort(compareByDistance);
const world = [
[["Start"], [20, 20]],
[["NY"], [29, 30]],
[["London"], [24, 27]],
[["Moscow"], [29, 32]],
[["Toronto"], [20, 23]],
];
const calcDist2Points = function (p2, p1) {
const r = 6371;
let d, dLat, dLon;
const lat2 = p2[0];
const lon2 = p2[1];
const lat1 = p1[0];
const lon1 = p1[1];
dLat = lat2 - lat1;
dLon = lon2 - lon1;
let a = Math.sin(dLat / 2) ** 2 + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
d = r * c;
return d; // distance in km
};
const calcDirectRoute = function (start, input) {
const cities = input.reduce((cities, [[name], coordinates]) => ({ ...cities, [name]: coordinates }), []);
const tripList = [];
let coordinates = cities[start];
do {
const [closest] = getDistances(coordinates, cities);
delete cities[closest.name];
coordinates = closest.coordinates;
tripList.push(closest);
} while (Object.keys(cities).length !== 0);
return formatOutput(tripList);
};
console.log(calcDirectRoute("Start", world));
推荐阅读
- java - 如何在 iText7 中为单个页面设置页面标签?
- git - 连接到一个空的 subversion 存储库
- c# - 如何通过普通 http 在 C# Kestrel Web 服务器中启用 http2?
- javascript - 是否可以从 Chrome 扩展程序中隐藏某个 HTML 元素?
- python - 由于 NaN/inf 或 dtype,我在 sklearn 中收到 ValueError。查了资料,没发现错误
- pandas - - 不支持的操作数类型:“列表”和“列表”
- kubernetes - k8s 中的 TLS 引导节点
- python - 需要一些帮助来理解作为函数的参数
- c++ - 如何在 C++ 中使用数学
- android - android studio:模拟器不能多次启动