最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Alternative to multiple "if statements? - Stack Overflow

programmeradmin3浏览0评论

I'm really new to HTML and Javascript. I'd appreciate any help with the code I'm writing.

I'm working on a calculator to display the distance between airports. The user will have five "text" inputs, so they will write airport codes, say MAD, JFK. The result would be the distance between Madrid and JFK. The user can add several airports such as BCN MAD JFK ORD, and the result should be the total addition of all legs (result = BCN-MAD + MAD-JFK + JFK-ORD).

For my purpose, it's also important that the distances are specified by me (so I dont need to "calculate" distances between coordinates).

What I've done is I've created variables called "leg1,2,3,4" which pair each airport, so leg1 can be for example "BCNMAD" and then using if statements I can get the distance for that leg. Finally there's a totalDistance variable to add all the leg distances.

Because each leg needs to be calculated separately and added to the other legs, I've copied the if statements for each separate leg.

This seems to work just fine, the problem is so far I've added just 8 airports. The actual requirement will be approx 200 airports. And because each leg has its own set of if, I could end up with about 800 IFs.

I was wondering if there's any better way to do this? Also, I dont know if there's a limit to how many if can be handled?

Like I said before I'm very new to HTML and Javascript so I'm sure there are much better options to do this, but I've been stuck with this issue for days and this is the best solution I could e up with.

So any advice or help would be very appreciated. I've included the code below.

regards, Mike

function displayDistance()
{
var leg1 = {route:document.getElementById("air1").value + document.getElementById("air2").value , distance:""};
var leg2 = {route:document.getElementById("air2").value + document.getElementById("air3").value , distance:""};
var leg3 = {route:document.getElementById("air3").value + document.getElementById("air4").value , distance:""};
var leg4 = {route:document.getElementById("air4").value + document.getElementById("air5").value , distance:""};

if (leg1.route == "AGPMAD" || leg1.route == "MADAGP") {leg1.distance = 430;}
if (leg1.route == "BCNMAD" || leg1.route == "MADBCN") {leg1.distance = 483;}
if (leg1.route == "LHRMAD" || leg1.route == "MADLHR") {leg1.distance = 1246;}
if (leg1.route == "CDGMAD" || leg1.route == "MADCDG") {leg1.distance = 1065;}
if (leg1.route == "JFKMAD" || leg1.route == "MADJFK") {leg1.distance = 5777;}
if (leg1.route == "ORDJFK" || leg1.route == "JFKORD") {leg1.distance = 1191;}
if (leg1.route == "JFKMCO" || leg1.route == "MCOJFK") {leg1.distance = 1520;}
if (leg1.route == "JFKIAD" || leg1.route == "IADJFK") {leg1.distance = 367;}

if (leg2.route == "AGPMAD" || leg2.route == "MADAGP") {leg2.distance = 430;}
if (leg2.route == "BCNMAD" || leg2.route == "MADBCN") {leg2.distance = 483;}
if (leg2.route == "LHRMAD" || leg2.route == "MADLHR") {leg2.distance = 1246;}
if (leg2.route == "CDGMAD" || leg2.route == "MADCDG") {leg2.distance = 1065;}
if (leg2.route == "JFKMAD" || leg2.route == "MADJFK") {leg2.distance = 5777;}
if (leg2.route == "ORDJFK" || leg2.route == "JFKORD") {leg2.distance = 1191;}
if (leg2.route == "JFKMCO" || leg2.route == "MCOJFK") {leg2.distance = 1520;}
if (leg2.route == "JFKIAD" || leg2.route == "IADJFK") {leg2.distance = 367;}

if (leg2.route == "AGPMAD" || leg2.route == "MADAGP") {leg2.distance = 430;}
if (leg3.route == "BCNMAD" || leg3.route == "MADBCN") {leg3.distance = 483;}
if (leg3.route == "LHRMAD" || leg3.route == "MADLHR") {leg3.distance = 1246;}
if (leg3.route == "CDGMAD" || leg3.route == "MADCDG") {leg3.distance = 1065;}
if (leg3.route == "JFKMAD" || leg3.route == "MADJFK") {leg3.distance = 5777;}
if (leg3.route == "ORDJFK" || leg3.route == "JFKORD") {leg3.distance = 1191;}
if (leg3.route == "JFKMCO" || leg3.route == "MCOJFK") {leg3.distance = 1520;}
if (leg3.route == "JFKIAD" || leg3.route == "IADJFK") {leg3.distance = 367;}

if (leg4.route == "AGPMAD" || leg4.route == "MADAGP") {leg4.distance = 430;}
if (leg4.route == "BCNMAD" || leg4.route == "MADBCN") {leg4.distance = 483;}
if (leg4.route == "LHRMAD" || leg4.route == "MADLHR") {leg4.distance = 1246;}
if (leg4.route == "CDGMAD" || leg4.route == "MADCDG") {leg4.distance = 1065;}
if (leg4.route == "JFKMAD" || leg4.route == "MADJFK") {leg4.distance = 5777;}
if (leg4.route == "ORDJFK" || leg4.route == "JFKORD") {leg4.distance = 1191;}
if (leg4.route == "JFKMCO" || leg4.route == "MCOJFK") {leg4.distance = 1520;}
if (leg4.route == "JFKIAD" || leg4.route == "IADJFK") {leg4.distance = 367;}

  
var totalDistance = leg1.distance + leg2.distance + leg3.distance + leg4.distance;
  
document.getElementById("distanceresult").innerHTML = totalDistance;
}
<span>Route: </span>
<input type="text" class="airinput" id="air1" value="" required=""/>
<input type="text" class="airinput" id="air2" value="" required=""/>
<input type="text" class="airinput" id="air3" value="" required=""/>
<input type="text" class="airinput" id="air4" value="" required=""/>
<input type="text" class="airinput" id="air5" value="" required=""/>
<br/>
<input type="button" onClick="displayDistance();" value="Calculate Distance"/><br/>
<span>The total distance is: </span><span id="distanceresult"></span><br/>

I'm really new to HTML and Javascript. I'd appreciate any help with the code I'm writing.

I'm working on a calculator to display the distance between airports. The user will have five "text" inputs, so they will write airport codes, say MAD, JFK. The result would be the distance between Madrid and JFK. The user can add several airports such as BCN MAD JFK ORD, and the result should be the total addition of all legs (result = BCN-MAD + MAD-JFK + JFK-ORD).

For my purpose, it's also important that the distances are specified by me (so I dont need to "calculate" distances between coordinates).

What I've done is I've created variables called "leg1,2,3,4" which pair each airport, so leg1 can be for example "BCNMAD" and then using if statements I can get the distance for that leg. Finally there's a totalDistance variable to add all the leg distances.

Because each leg needs to be calculated separately and added to the other legs, I've copied the if statements for each separate leg.

This seems to work just fine, the problem is so far I've added just 8 airports. The actual requirement will be approx 200 airports. And because each leg has its own set of if, I could end up with about 800 IFs.

I was wondering if there's any better way to do this? Also, I dont know if there's a limit to how many if can be handled?

Like I said before I'm very new to HTML and Javascript so I'm sure there are much better options to do this, but I've been stuck with this issue for days and this is the best solution I could e up with.

So any advice or help would be very appreciated. I've included the code below.

regards, Mike

function displayDistance()
{
var leg1 = {route:document.getElementById("air1").value + document.getElementById("air2").value , distance:""};
var leg2 = {route:document.getElementById("air2").value + document.getElementById("air3").value , distance:""};
var leg3 = {route:document.getElementById("air3").value + document.getElementById("air4").value , distance:""};
var leg4 = {route:document.getElementById("air4").value + document.getElementById("air5").value , distance:""};

if (leg1.route == "AGPMAD" || leg1.route == "MADAGP") {leg1.distance = 430;}
if (leg1.route == "BCNMAD" || leg1.route == "MADBCN") {leg1.distance = 483;}
if (leg1.route == "LHRMAD" || leg1.route == "MADLHR") {leg1.distance = 1246;}
if (leg1.route == "CDGMAD" || leg1.route == "MADCDG") {leg1.distance = 1065;}
if (leg1.route == "JFKMAD" || leg1.route == "MADJFK") {leg1.distance = 5777;}
if (leg1.route == "ORDJFK" || leg1.route == "JFKORD") {leg1.distance = 1191;}
if (leg1.route == "JFKMCO" || leg1.route == "MCOJFK") {leg1.distance = 1520;}
if (leg1.route == "JFKIAD" || leg1.route == "IADJFK") {leg1.distance = 367;}

if (leg2.route == "AGPMAD" || leg2.route == "MADAGP") {leg2.distance = 430;}
if (leg2.route == "BCNMAD" || leg2.route == "MADBCN") {leg2.distance = 483;}
if (leg2.route == "LHRMAD" || leg2.route == "MADLHR") {leg2.distance = 1246;}
if (leg2.route == "CDGMAD" || leg2.route == "MADCDG") {leg2.distance = 1065;}
if (leg2.route == "JFKMAD" || leg2.route == "MADJFK") {leg2.distance = 5777;}
if (leg2.route == "ORDJFK" || leg2.route == "JFKORD") {leg2.distance = 1191;}
if (leg2.route == "JFKMCO" || leg2.route == "MCOJFK") {leg2.distance = 1520;}
if (leg2.route == "JFKIAD" || leg2.route == "IADJFK") {leg2.distance = 367;}

if (leg2.route == "AGPMAD" || leg2.route == "MADAGP") {leg2.distance = 430;}
if (leg3.route == "BCNMAD" || leg3.route == "MADBCN") {leg3.distance = 483;}
if (leg3.route == "LHRMAD" || leg3.route == "MADLHR") {leg3.distance = 1246;}
if (leg3.route == "CDGMAD" || leg3.route == "MADCDG") {leg3.distance = 1065;}
if (leg3.route == "JFKMAD" || leg3.route == "MADJFK") {leg3.distance = 5777;}
if (leg3.route == "ORDJFK" || leg3.route == "JFKORD") {leg3.distance = 1191;}
if (leg3.route == "JFKMCO" || leg3.route == "MCOJFK") {leg3.distance = 1520;}
if (leg3.route == "JFKIAD" || leg3.route == "IADJFK") {leg3.distance = 367;}

if (leg4.route == "AGPMAD" || leg4.route == "MADAGP") {leg4.distance = 430;}
if (leg4.route == "BCNMAD" || leg4.route == "MADBCN") {leg4.distance = 483;}
if (leg4.route == "LHRMAD" || leg4.route == "MADLHR") {leg4.distance = 1246;}
if (leg4.route == "CDGMAD" || leg4.route == "MADCDG") {leg4.distance = 1065;}
if (leg4.route == "JFKMAD" || leg4.route == "MADJFK") {leg4.distance = 5777;}
if (leg4.route == "ORDJFK" || leg4.route == "JFKORD") {leg4.distance = 1191;}
if (leg4.route == "JFKMCO" || leg4.route == "MCOJFK") {leg4.distance = 1520;}
if (leg4.route == "JFKIAD" || leg4.route == "IADJFK") {leg4.distance = 367;}

  
var totalDistance = leg1.distance + leg2.distance + leg3.distance + leg4.distance;
  
document.getElementById("distanceresult").innerHTML = totalDistance;
}
<span>Route: </span>
<input type="text" class="airinput" id="air1" value="" required=""/>
<input type="text" class="airinput" id="air2" value="" required=""/>
<input type="text" class="airinput" id="air3" value="" required=""/>
<input type="text" class="airinput" id="air4" value="" required=""/>
<input type="text" class="airinput" id="air5" value="" required=""/>
<br/>
<input type="button" onClick="displayDistance();" value="Calculate Distance"/><br/>
<span>The total distance is: </span><span id="distanceresult"></span><br/>

Share Improve this question asked Jan 21, 2017 at 16:06 Mike1986Mike1986 631 silver badge5 bronze badges 1
  • 1 Instead of using leg1 ... leg4 create an array. Iterate over it so you loose the duplicated (quadrupled) code. If this is not enough, ditch the if clauses and use a single switch. – alesc Commented Jan 21, 2017 at 16:09
Add a ment  | 

5 Answers 5

Reset to default 5

Instead of hardcoding your data into a long set of conditionals you are better using an object. This lends itself better to transitioning to a databased solution, which would be the way this is normally handled.

var distances_ = {
  "AGPMAD": 430,
  "MADAGP": 430,
  "BCNMAD": 483,
  "LHRMAD": 1246,
};
leg1.distance =  distances_[ leg1.route ] );

If you are operating entirely in Javascript, you can use a JSON text file and an AJAX call in place of a database to remove the distance data entirely from your code.

There is no need to duplicate each block of if statements, you should turn them into a function and then do something like this:

function getLegDistance(route) {
    if (route == "AGPMAD" || route == "MADAGP") return 430;
    if (route == "BCNMAD" || route == "MADBCN") return 483;
    if (route == "LHRMAD" || route == "MADLHR") return 1246;
    if (route == "CDGMAD" || route == "MADCDG") return 1065;
    if (route == "JFKMAD" || route == "MADJFK") return 5777;
    if (route == "ORDJFK" || route == "JFKORD") return 1191;
    if (route == "JFKMCO" || route == "MCOJFK") return 1520;
    if (route == "JFKIAD" || route == "IADJFK") return 367;
}

var totalDistance = getLegDistance(leg1.route) + getLegDistance(leg2.route) + getLegDistance(leg3.route) + getLegDistance(leg4.route)

That way you only have one block of if statements, and you can call it for every route you have. You could also use a switch statement instead of all of the if statements but it won't cut down on your line count (it would improve your performance though), so an object/map would probably be better.

Use the switch.

Here is the reference:

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Statements/switch

example:

switch (expression) {
  case value1:
    //Statements executed when the result of expression matches value1
    [break;]
  case value2:
    //Statements executed when the result of expression matches value2
    [break;]
  ...
  case valueN:
    //Statements executed when the result of expression matches valueN
    [break;]
  default:
    //Statements executed when none of the values match the value of the expression
    [break;]
}

This was definitely an interesting problem! I worked on a solution for a bit. I saw a lot duplication in the airport codes and realized how out of hand this could get. They could be both MADAGP or AGPMAD. It is a really good practice to have your data structures inform your code rather than your code inform how you store your data. You can store all of your airport data in an object and reference that object to get the distance. I saw a mon pattern, it could be either [key][value] or [value][key]. To solve this problem I used the lodash forEach function. You can see here in a fiddle all of it working! Please let me know if you have any questions :)

function displayDistance() {

    var routes = {
        MAD: {
            AGP: 430,
            BCN: 483,
            LHR: 1246,
            CDG: 1065,
            JFK: 5777,
        },
        JFK: {
            ORD: 1191,
            MCO: 1520,
            IAD: 367,
            MAD: 5777,
        }
    };

    var leg1 = {
        departingCity: document.getElementById("air1").value,
        arrivalCity: document.getElementById("air2").value,
    };

    var leg2 = {
        departingCity: document.getElementById("air2").value,
        arrivalCity: document.getElementById("air3").value,
    };

    var leg3 = {
        departingCity: document.getElementById("air3").value,
        arrivalCity: document.getElementById("air4").value,
    };

    var leg4 = {
        departingCity: document.getElementById("air4").value,
        arrivalCity: document.getElementById("air5").value,
    };

    function getDistance(departingCity, arrivalCity, routes) {
        var distance
        _.forEach(routes, function(_value, key) { 
            if(departingCity ===  key) {
                distance = routes[departingCity][arrivalCity]
            } else if (arrivalCity === key) {
                distance = routes[arrivalCity][departingCity]
            } 
        });
        return distance
    };


    var totalDistance = getDistance(leg1.departingCity, leg1.arrivalCity, routes) 
        + getDistance(leg2.departingCity, leg2.arrivalCity, routes)
        + getDistance(leg3.departingCity, leg3.arrivalCity, routes)
        + getDistance(leg4.departingCity, leg4.arrivalCity, routes)

    document.getElementById("distanceresult").innerHTML = totalDistance;
}

Here's how I would approach this problem.

First, build a data structure that contains each of the distances. For this, I have made the following assumptions:

  1. That the distance from airport 1 to airport 2 is always the same as the distance from airport 2 to airport 1 for all possible airports in the dataset.

  2. That the distance from any airport to any other airport in the dataset can be defined as a single constant number.

In JavaScript, that data structure can be expressed like this (though you may be better storing this as a JSON object):

var routes = {

    BCN: {

        MAD: 483

    },

    JFK: {

        MAD: 5761,
        BCN: 6150

    },

    LHR: {

        MAD: 1244,
        BCN: 1148,
        JFK: 5539

    },

    ORD: {

        MAD: 6744,
        BCN: 7093,
        JFK: 1188,
        LHR: 6343

    }
};

Note that each property refers to each property above it and the root case 'MAD', but not below. This removes the redundancy of having to store each value twice. It also makes it a lot simpler to add more data as you only need to add a definition and distances for each subsequent airport, without the need to modify the previous data.

Now you just need a function to read that data structure. This basic one seems quite adequate:

function getDistance (airport1, airport2) {

    if (routes [airport1] && routes [airport1][airport2])
        return routes [airport1][airport2];

    if (routes [airport2] && routes [airport2][airport1])
        return routes [airport2][airport1];

    return null;

}

Depending on your requirements, you may need to customise the fall-through case return null;, but otherwise, this should fit your needs.

发布评论

评论列表(0)

  1. 暂无评论