Sunny Kumar
Sunny Kumar

Reputation: 81

Avoiding very much if else in code

function get_map_zoom_level(distance) {
    var zoom = 1;
    if (distance == 0)
        zoom = 11;
    else if (distance == 1)
        zoom = 15;
    else if (distance > 880 && distance <= 1760)
        zoom = 14;
    else if (distance > 1760 && distance <= 3520)
        zoom = 13;
    else if (distance > 3520 && distance <= 7040)
        zoom = 12;
    else if (distance > 7040 && distance <= 14080)
        zoom = 11;
    else if (distance > 14080 && distance <= 28160)
        zoom = 10;
    else if (distance > 28160 && distance <= 56320)
        zoom = 9;
    else if (distance > 56320 && distance <= 112640)
        zoom = 8;
    else if (distance > 112640 && distance <= 225280)
        zoom = 7;
    else if (distance > 225280 && distance <= 450560)
        zoom = 6;
    else if (distance > 450560 && distance <= 889120)
        zoom = 5;
    else if (distance > 889120 && distance <= 1718240)
        zoom = 4;
    else if (distance > 1718240)
        zoom = 3;
    return zoom;
}

I want to know if there is any way to avoid many if else in this code. Basically I want to find out zoom level on the basis of distance, this code is working perfectly but I need some better way to do this.

Upvotes: 3

Views: 204

Answers (4)

Rhumborl
Rhumborl

Reputation: 16609

When you have a large number of if statements comparing the same data as yours is, the usual approach is to create an Array, where each entry contains the data to compare and the result, in other words the minimum distance, the maximum distance, and the zoom level.

To do the comparison, you use a for loop to go through the array, checking the values for each. if you find a matching entry, then set the result and break out of the loop.

This is not more efficient or quicker than the way you have done it, but it means you can have any number of options and your actual code doesn't get bigger or more complicated.

Here is how you can do this with yours:

function get_map_zoom_level(distance) {

    // create the array of values. Each entry can be either an array or an object, doesn't matter too much.
    // I'll use an array set up as [minDistance, maxDistance, zoom]
    var zoomLevels = [
        [880, 1760, 14],
        [1760, 3520, 13],
        [3520, 7040, 12],
        [7040, 14080, 11],
        // ... etc.
    ]

    var zoom = 1;
    // special cases
    if (distance == 0)
        zoom = 11;
    else if (distance == 1)
        zoom = 15;
    else if (distance > 1718240)
        zoom = 3;
    else {
        for (var i = 0; i < zoomLevels.length; i++) {
            var zoomLevel = zoomLevels[i];
            if (distance > zoomLevel[0] && distance <= zoomLevel[1]) {
                zoom = zoomLevel[2];
                // found a match - stop the loop
                break;
            }
        }
    }

    return zoom;

}

By the way, zoom level 11 seems to have an error in it, 7040 and 1480 don't match.

Upvotes: 3

xnakos
xnakos

Reputation: 10196

The following code keeps the exact same edge cases (explicit, e.g. distance is 0 -> zoom is 11, and implicit, e.g. distance is 42 -> zoom is 1) that your code has in the same order as well, but, if we are not dealing with an edge case, decides on the applicable intermediate range using an array of distances in ascending order, representing inclusive upper bounds (of ranges). The exclusive lower bound is handled by iterating the array from the beginning, since the values are ascending.

function get_map_zoom_level(distance) {
    var distanceBreakpoints = [1760, 3520, 7040, 14080, 28160, 56320, 112640, 225280, 450560, 889120, 1718240];
    var zoom = 1;
    if (distance == 0)
        zoom = 11;
    else if (distance == 1)
        zoom = 15;
    else if (distance > 880 && distance <= 1718240) {
        for (var i = 0; i < distanceBreakpoints.length; ++i) {
            if (distance <= distanceBreakpoints[i]) {
                zoom = 14 - i;
                break;
            }
        }
    } else if (distance > 1718240)
        zoom = 3;
    return zoom;
}

Upvotes: 0

agni10
agni10

Reputation: 154

This should work:

function get_map_zoom_level(distance) {
var zoom = 15;
var temp=880;
if (distance == 0)
    zoom = 11
while (distance > temp){
    temp=temp*2;
    zoom--;
}
return zoom;
}

Upvotes: 3

Lu&#237;s Soares
Lu&#237;s Soares

Reputation: 6202

You could have an object like:

var zooms = [ { min:1480 , max:28160} ,  // array index is zoom level
              // ...
              { min:880 , max:1760} ];

and then iterate it until the zoom is found

for(var z = 1 ; z <= MAX_ZOOM ; z++) {
    if (distance > zooms[z].min && distance <= zooms[z].max) {
        return z;
    }
}

In Java, it would be easier.

Upvotes: 2

Related Questions