如何正确使用数组解决问题? Java脚本

时间:2019-05-14 04:04:23

标签: javascript html arrays

我在弄清楚如何正确使用距离数组时遇到麻烦。我正在创建一个简单的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>

4 个答案:

答案 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是一个不错的起点,但绝非易事。基本上给定了一个起始城市,我们研究出如何以“成本”(距离或时间)最低的方式分支到后续可用的城市,直到到达目标城市。