javascriptif-statementfitbit

Condense an if statement to find what range a value fits in


So I'm trying to make a compass app for the Fitbit Ionic, it works but this piece of code makes me angry. I know there's a way to condense it but I can't figure out how. It is supposed to take an integer and tell me what is the corresponding cardinal direction.

It would look so much better if that if statement could be condensed. Any advice or solutions are greatly appreciated.

geolocation.watchPosition(function(position) {
var headingDir;
var headingDeg;
headingDeg = position.coords.heading ? position.coords.heading.toFixed(2) : 0

//This long boi
 if (headingDeg >= 22.5 & headingDeg < 67.5) {
  headingDir = "NE";
 } else if (headingDeg >= 67.5 & headingDeg < 112.5) {
  headingDir = "E"
 } else if (headingDeg >= 112.5 & headingDeg < 157.5) {
  headingDir = "SE"
 } else if (headingDeg >= 157.5 & headingDeg < 202.5) {
  headingDir = "S"
 } else if (headingDeg >= 202.5 & headingDeg < 247.5) {
  headingDir = "SW"
 } else if (headingDeg >= 247.5 & headingDeg < 292.5) {
  headingDir = "W"
 } else if (headingDeg >= 292.5 & headingDeg < 337.5) {
  headingDir = "NW"
 } else {
  headingDir = "N"
 };

})

Solution

  • Because each range differs by the same amount (45), you can make an array for the direction strings, and then calculate the index of the direction string you want immediately:

    const headingStrs = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'];
    const getHeading = (deg) => headingStrs[Math.floor((deg + 22.5) / 45)];
    
    console.log(getHeading(30)); // NE
    console.log(getHeading(300)); // NW
    console.log(getHeading(170)); // S
    console.log(getHeading(22.5)); // NE
    console.log(getHeading(15)); // N