HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Mapping Yahoo weather codes to CSS classes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cssyahoocodesclassesmappingweather

Problem

I created a weather widget in JavaScript that requests the current weather from Yahoo. The weather request returns a code which corresponds with a current weather image. I don't like Yahoo's images, so I use my own CSS classes that correspond with my own images. Consequently, the following code returns the correct CSS class which I then deal with later:

function returnClass(c) {
    if (c === "0" || c === "19" || c === "23" || c === "24") {
        return ["basecloud", "wind"];
    } else if (c === "1" || c === "2") {
        return ["basecloud", "rain"];
    } else if (c === "3" || c === "4" || c === "37" || c === "38" || c === "39" || c === "45" || c === "47") {
        return ["basecloud", "thunder"];
    } else if (c === "5" || c === "6" || c === "7" || c === "8" || c === "10" || c === "18") {
        return ["basecloud", "sleet"];
    } else if (c === "9") {
        return ["basecloud", "drizzle"];
    } else if (c === "11" || c === "12" || c === "40") {
        return ["basecloud", "rain"];
    } else if (c === "13" || c === "14" || c === "15" || c === "16" || c === "41" || c === "42" || c === "43" || c === "46") {
        return ["basecloud", "snow"];
    } else if (c === "17" || c === "35") {
        return ["basecloud", "hail"];
    } else if (c === "20" || c === "21" || c === "22") {
        return ["mist"];
    } else if (c === "25") {
        return ["basecloud", "frost"];
    } else if (c === "26" || c === "27" || c === "29" || c === "33" || c === "28" || c === "30" || c === "34" || c === "44") {
        return ["cloud"];
    } else if (c === "31") {
        return ["moon"];
    } else if (c === "32" || c === "36") {
        return ["sun"];
    } else if (c === "3200") {
        return ["none"];
    }
}


Is there any way to simplify the above code? As you can tell, multiple codes can represent the same CSS class, which is why I have so many or operators. The only requirement is that it returns the correct array depending on the code.

Solution

This sort of thing, with a finite set of coditions, is typically done using an array:

var codeIcons=[
      ["basecloud", "wind"],
      ["basecloud", "rain"],
      ["basecloud", "rain"],
      ["basecloud", "thunder"],
      ["basecloud", "thunder"],
      ....
    ];


Then your method simply becomes:

function returnClass(c) {
    c = parseInt(c);
    return (c < codeIcons.length) ? codeIcons[c] : ["none"];
}


Just adding to a set of advantages this method has:

  • sure, it is hard-coding logic, but, the presentation is better than multiple if-statements.



  • it is more managable - you can easily add conditions



  • you know exactly what conditions lead to certain output (you do not need to scan pages of code to find the right conditions



  • you cannot have bugs where multiple conditions lead to the same result (these types of bugs tend to creep in after maintaining the code - you have multiple or-conditions where c == xxx.



  • if, further down the road, you want to migrate the logic for what classes/icons to use, and when, you can easily just change where the array-of-values is configured (i.e. it can become a configuration value, not hard-coded.)

Code Snippets

var codeIcons=[
      ["basecloud", "wind"],
      ["basecloud", "rain"],
      ["basecloud", "rain"],
      ["basecloud", "thunder"],
      ["basecloud", "thunder"],
      ....
    ];
function returnClass(c) {
    c = parseInt(c);
    return (c < codeIcons.length) ? codeIcons[c] : ["none"];
}

Context

StackExchange Code Review Q#37974, answer score: 16

Revisions (0)

No revisions yet.