缩短Javascript if-else结构

时间:2013-07-16 14:28:08

标签: javascript

我的代码是:

 var level = function (d) {
    if (value(d) > median + stdev) {
        return 1;
    } else if (value(d) > median) {
        return 2;
    } else if (value(d) > median - stdev) {
        return 3;
    } else {
        return 4;
    }
 };

有更好的方法吗?

14 个答案:

答案 0 :(得分:15)

当然,多次调用value(d)是可以避免的。

您也可以使用symmetry

缩短一点
  var level = function (d) {
    //
    //               -std    median  +std
    // ----------------|-------|-------|------------------
    // 4444444444444444 3333333 2222222 111111111111111111
    //
    var i = Math.floor((median - value(d)) / stddev) + 3;
    return Math.max(1, Math.min(4, i));
  };

对于一个真正的项目可能不是一个好主意但是...我没有测试但是我发现这个代码比你问题中的原始代码慢,我不会感到惊讶,并且我发现它更难维持。

请注意,排除一次性一次性脚本通常会编写一次代码并多次读取(用于维护,如改进或调试),因此更容易阅读"通常比#34更容易;更容易写"。

当更短的意思更容易阅读"当它开始意义时更难以阅读"更难阅读"它没有。

答案 1 :(得分:7)

要完成设置,以下是@austin引用的switch方式:

var level = function (d) {
  var d = value(d) - median;
  switch (true) {
  case d > stdev : return 1;
  case d > 0:      return 2;
  case d > -stdev: return 3;
  default:         return 4;
  }
};

答案 2 :(得分:4)

这个解决方案更好,但我不建议在生产中使用它,因为它有点令人困惑:

4 - [median + stdev, median, median - stdev].filter(function(e, i, a) {
    return value(d) > e;
}).length 

答案 3 :(得分:3)

您可以计算值和中位数之间的差异,这使得比较更简单:

function level(d) {
  var n = value(d) - median;
  if (n > stdev) {
    return 1;
  } else if (n > 0) {
    return 2;
  } else if (n > -stdev) {
    return 3;
  } else {
    return 4;
  }
};

您也可以使用条件运算符而不是if语句来编写它:

function level(d) {
  var n = value(d) - median;
  return n > stdev ? 1 :
    n > 0 ? 2 :
    n > -stdev ? 3 :
    4;
  }
};

这是否更好是一个品味问题,但它更短。

答案 4 :(得分:2)

“更好”的方式?不,不是真的。

替代方式 - 是的,很多。

一种可能性是将条件和结果存储在数组中

var levelFunctions = [
  { func: function(d){ return value(d) > median + stdev; }, val:1},
  { func: function(d){ return value(d) > median ; }, val:2},
  { func: function(d){ return value(d) > median - stdev; }, val:3},
  { func: function(d){ return true; }, val:4}
];

然后只列举该列表作为函数的一部分

var level = function (d) {
    for(var i=0;i<levelFunctions.length;i++){
       if(levelFunctions[i].func(d))
           return levelFunctions[i].val;
    }
 };

比原来有点容易扩展,但 [diety] 丑陋如罪!

答案 5 :(得分:2)

我认为没有太多改进空间可以保证起始案例的可读性。如果你真的归还了整数,并且它们不仅仅是为了这个例子,我建议你返回更有意义的东西。

你可以肯定只计算一次value(d)

var level = function (d) {
  var dValue = value(d);
  if (dValue > median + stdev) {
    return 1;
  } else if (dValue > median) {
    return 2;
  } else if (dValue > median - stdev) {
    return 3;
  } else {
   return 4;
  }
};

另外,你可能想避免多次退货,或者你可能不这样做,对我来说它们是相同的,每种都有优点/缺点:

var level = function (d) {
  var dValue = value(d),
      code = 4;
  if (dValue > median + stdev) {
    code = 1;
  } else if (dValue > median) {
    code = 2;
  } else if (dValue > median - stdev) {
    code = 3;
  } 
  return code;
};

如果您为code分配了一个有意义的名称,那么您正在向正在阅读您的代码的人提供更多信息。

答案 6 :(得分:2)

我建议避免多次调用value

function level(d) {
    var diff = value(d) - median;
    if (diff > 0) {
        if (diff > stdev)
            return 1;
        else
            return 2;
    else
        if (diff > -stdev)
            return 3;
        else
            return 4;
}

此外,我将if-else-statements嵌套在(希望)更有意义的结构中 - 这取决于你的用例。如果您返回-2-112之类的值,可能会更有用。一个三元运算符可以为你节省一些写作,但它不一定会变得更清晰。

或者,一些数学可以帮助你:

function level(d) {
    var diff = value(d) - median;
    return 2 + (diff > 0 ? -.5 : .5) * (Math.abs(diff) > stdev ? 3 : 1);
}

虽然在3的情况下会导致4而不是value(d) === median-stdev。请参阅@ 6502关于如何避免这种情况的答案。

答案 7 :(得分:2)

好吧,如果我们想要简短的创意解决方案......

var level = function(d){
    d = value(d);
    return +(d<=median+stdev)+ +(d<=median)+ +(d<=median-stdev) + 1
}

答案 8 :(得分:1)

您可以使用switch语句(Mozilla Developer Network docs)。

编辑:如果您认为在switch语句中无法执行范围,则此处为answer to a similar question

答案 9 :(得分:1)

这不会删除if / else结构,但会使代码更清晰:

var level = function (d) {
    var delta = value(d) - median;
    if (delta > stdev) {
        return 1;
    } else if (delta > 0) {
        return 2;
    } else if (delta > -stdev) {
        return 3;
    } else {
        return 4;
    }
 };

只有一次调用value(d)还有额外的好处。

答案 10 :(得分:1)

另一种选择 - 忽略数学在这种情况下的有用性 - 是完全取消if语句。我通常更喜欢这种使用三元运算符的方法。我倾向于认为这比具有多个if / else结构(对于简单情况)更具可读性,但这仅仅是因为我精通JavaScript的逻辑运算符。我完全可以理解这些学习有多奇怪,或者用1 && 3 === TRUE而非3

的奇怪和外语编码的人
var level = function (d) {
  d = value(d);
  return ((d > median + stdev) && 1) 
      || ((d > median)         && 2) 
      || ((d > median - stdev) && 3)
      || 4
  ;
}

进一步可能的优化 - 这个问题的独特之处 - 是从比较中删除median,但这很可能会影响可读性:

var level = function (d) {
  d = value(d) - median;
  return ((d > + stdev) && 1) 
      || ((d > 0)       && 2) 
      || ((d > - stdev) && 3)
      || 4
  ;
}

答案 11 :(得分:1)

var level = function(d){
    var n = value(d) - median, values = [];
    values[stdev]  = 1;
    values[0]      = 2;
    values[-stdev] = 3;
    return values[n] ? values[n] : 4;
};
如果需要,

values可以退出功能范围。

答案 12 :(得分:1)

我不会碰这个代码。

此处有许多已发布的代码,但您的可读性仍然最高。

答案 13 :(得分:0)

试试这个......

  var reduceCalcVal=value(d);   //reduce repeated calculation
  var cheats=new Array( reduceCalcVal > median + stdev
    ,reduceCalcVal  > median, reduceCalcVal > median - stdev);
    n=(cheats.indexOf(true)==-1)?4:cheats.indexOf(true)+1;
    alert(n)