我在弄清楚如何正确使用距离数组时遇到麻烦。我正在创建一个简单的Web应用程序,用户将在其中选择其来源和首选目的地,并且需要计算ETA。我已经可以计算出ETA了,但是代码太长了,所以我想知道是否有更好的方法可以做到这一点。 例如: 1)在选择选项中,我有4个位置,分别是马尼拉,QC,Makati和marikina。 2)如果用户选择马尼拉作为起点,并将质量控制作为目的地,则只能使用if-else进行计算,但是如果我考虑各种可能的方式,则使用if-else语句会使我的代码很长。
顺便说一句,这只是选择选项的示例数据,真实数据由24个位置和目的地组成。所以我真的希望我可以有一个简单的方法来做到这一点。
我只尝试了if-else语句,我在想也许我只是循环它,但不知道如何开始。 请参阅代码以供参考。谢谢!
console.clear()
function validateSelect(e) {
var origin = e.target.querySelector("[name=origin]").value;
var destination = e.target.querySelector("[name=destination]").value;
if (origin == destination) {
e.stopPropagation()
e.preventDefault()
alert("Origin and Destination can't be the same");
return false;
}
}
var distanceArray = [10000,20000,30000];
//manila to qc 10000 meter
//qc to makati 20000 meter
//makati to marikina 30000 meter
document.getElementById('findEta').addEventListener('submit', validateSelect);//for form find eta
function getEta(){
var selectedOrigin = document.getElementById("origin").selectedIndex;
var selectedDestination = document.getElementById("destination").selectedIndex;
var estimatedTimeOfArrival = document.getElementById("estimatedTimeOfArrival");
if((selectedOrigin == 0)&& (selectedDestination == 1)){
//manila to qc
distance = 10000;
var speed = 5.56; //converted speed from 20km/h
time = distance/speed;
eta = Math.floor(time).toString();
if((eta >=60)){
var newEta = eta /60; //minutes
var mod = eta%60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m "+mod+"s" ;
}else{
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
}else if((selectedOrigin == 0)&& (selectedDestination == 2)){
distance = 20000;
var speed = 5.56;
time = distance/speed;
eta = Math.floor(time).toString();
if((eta >=60)){
var newEta = eta /60; //minutes
var mod = eta%60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m "+mod+"s" ;
}else{
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
}else if((selectedOrigin == 0)&& (selectedDestination == 2)){
distance = 30000;
var speed = 5.56;
time = distance/speed;
eta = Math.floor(time).toString();
if((eta >=60)){
var newEta = eta /60; //minutes
var mod = eta%60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m "+mod+"s" ;
}else{
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
}
}
function alertFunction(){
var selectedOrigin = document.getElementById("origin").value;
var selectedDestination = document.getElementById("destination").value;
var estimatedTimeOfArrival = document.getElementById("estimatedTimeOfArrival");
if((selectedOrigin == "")&&(selectedDestination =="")){
alert("Please select an option first.");
}else if(selectedOrigin == selectedDestination){
validateSelect(e);
}
else{
getEta();
alert("\nYour Origin is: "+selectedOrigin+"\nYour Destination is: "+selectedDestination+"\nYour ETA is: "+estimatedTimeOfArrival.value);
}
}
<form action="" id="findEta">
<select name="origin" id="origin">
<option value="manila">manila</option>
<option value="QC">QC</option>
<option value="makati">Makati</option>
<option value="marikina">marikina</option>
</select>
<select name="destination" id="destination">
<option value="manila">manila</option>
<option value="QC">QC</option>
<option value="makati">Makati</option>
<option value="marikina">marikina</option>
</select>
<input type="hidden" name="estimatedTimeOfArrival"id="estimatedTimeOfArrival">
<button type="submit" value="submit" onclick="alertFunction()">submit</button>
</form>
答案 0 :(得分:2)
我们可以排除从A点到A点的行程(0距离),并且可以假定从A点到B点的行程与反向行程的距离相同。这样,将地点表示为单个字母(a,b,c,d),就可以像这样紧凑地描述距离矩阵...(具有固定的距离值)
let distances = {
ab: 1000,
ac: 2000,
ad: 3000,
bc: 1500,
bd: 2500,
cd: 1200
}
function distance(from, to) {
let key = [from, to].sort().join('')
return distances[key]
}
console.log(distance('d', 'a'))
console.log(distance('b', 'c'))
答案 1 :(得分:1)
如果我的理解是正确的,则每种方法的ETA计算都是相同的,变量是起点和终点,它们共同为您提供距离。
为简化逻辑,您可以做的就是将这些索引所存储的距离存储在对象或多维数组中,例如:
const distances = {
0: {
1: 10000,
2: 20000
},
...
}
然后只需查找到那里的距离,例如:
const distance = distances[selectedOrigin][selectedDestination];
const speed = 5.56;
...
要更进一步,您可以通过直接在对象中使用名称值来简化结构的读取,例如:
const distances = {
manila: {
qc: 10000,
makati: 20000
},
...
}
然后在查找过程中使用这些值,例如:
const selectedOrigin = document.getElementById("origin").value;
const selectedDestination = document.getElementById("destination").value;
const distance = distances[selectedOrigin][selectedDestination];
const speed = 5.56;
...
答案 2 :(得分:1)
我会考虑将所有信息保存在JSON对象或类似对象中。
然后,您可以根据对象动态填充下拉列表,包括根据起点动态填充目标下拉列表。
由于我们是根据原点动态填充目的地,因此可以通过直接将距离作为目的地选项的值来保存查找
//Object to hold info
//Adjust distances as required
const origins = {
"manila": {
"name": "Manilla",
"distances": {
"QC": 1000,
"makati": 2000,
"marikina": 3000
}
},
"QC": {
"name": "QC",
"distances": {
"manila": 1000,
"makati": 2000,
"marikina": 3000
}
},
"makati": {
"name": "Makati",
"distances": {
"manila": 2000,
"QC": 2000,
"marikina": 3000
}
},
"marikina": {
"name": "Marikina",
"distances": {
"manila": 3000,
"QC": 3000,
"makati": 3000
}
}
}
let originDD = document.getElementById("origin");
let destinationDD = document.getElementById("destination");
originDD.innerHTML = "<option value=''>Please Select</option>"
//Populate Origins
for (var prop in origins) {
originDD.innerHTML += `<option value=${prop}>${origins[prop].name}</option>`;
}
//Populate Destinations on change
originDD.addEventListener("change", function() {
var thisOrigin = this.value;
destinationDD.innerHTML = "<option value=''>Please Select</option>";
for (var dest in origins[thisOrigin].distances) {
console.log(dest);
console.log(origins[dest])
destinationDD.innerHTML += `<option value=${origins[thisOrigin].distances[dest]}>${origins[dest].name}</option>`
}
});
//Calculate on destination change
destinationDD.addEventListener("change", function() {
var distance = parseInt(this.value, 10);
var speed = 5.56; //converted speed from 20km/h
var time = distance / speed;
var eta = Math.floor(time).toString();
var estimatedTimeOfArrival = document.getElementById("estimatedTimeOfArrival");
console.log(eta)
if ((eta >= 60)) {
var newEta = eta / 60; //minutes
var mod = eta % 60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m " + mod + "s";
} else {
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
document.querySelector("#eta > span").innerHTML = estimatedTimeOfArrival.value;
});
<form action="" id="findEta">
<select name="origin" id="origin">
</select>
<select name="destination" id="destination">
<option value="">Please Select Origin</option>
</select>
<input type="hidden" name="estimatedTimeOfArrival" id="estimatedTimeOfArrival">
<div id="eta">ETA: <span></span></div>
</form>
答案 3 :(得分:0)
您所追求的似乎是Travelling Salesman problem。这被认为是一个很难解决的问题,并且可能超出了常规Stack Overflow答案的范围,特别是如果它将是24个城市(对4个城市来说还算不错的话)。
Branch and Bound algorithm是一个不错的起点,但绝非易事。基本上给定了一个起始城市,我们研究出如何以“成本”(距离或时间)最低的方式分支到后续可用的城市,直到到达目标城市。