17

私が持っているコードは次のとおりです。

 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;
    }
 };

これを行うより良い方法はありますか?

4

14 に答える 14

7

セットを完成させるために、switch@austin が参照している方法は次のとおりです。

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;
  }
};
于 2013-07-16T14:53:14.143 に答える
4

このソリューションはより優れていますが、混乱を招くため、本番環境で使用することはお勧めしません。

4 - [median + stdev, median, median - stdev].filter(function(e, i, a) {
    return value(d) > e;
}).length 
于 2013-07-16T14:38:18.623 に答える
2

簡潔で創造的な解決策を求めるなら...

var level = function(d){
    d = value(d);
    return +(d<=median+stdev)+ +(d<=median)+ +(d<=median-stdev) + 1
}
于 2013-07-17T02:10:37.637 に答える
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の代わりにつながるが。それを回避する方法については、@ 6502 の回答を参照してください。4value(d) === median-stdev

于 2013-07-16T14:38:58.840 に答える
2

「より良い」方法?いいえ、そうではありません。

別の方法 - はい、たくさんあります。

1つの可能性は、条件と結果を配列に格納することです

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]によってそれは罪のように醜いです!

于 2013-07-16T14:37:27.123 に答える
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、コードを読んでいる人により多くの情報を提供できます。

于 2013-07-16T14:38:18.840 に答える
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
  ;
}
于 2013-07-16T19:41:06.567 に答える
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)は 1 回で済むという追加の利点があります。

于 2013-07-16T14:38:25.577 に答える
1

switchステートメントを使用できます( Mozilla Developer Network docs )。

編集: switch ステートメントで範囲を指定することが不可能だと思われる場合は、同様の質問に対する回答をご覧ください。

于 2013-07-16T14:29:20.947 に答える
1

コードには触れません。

ここには多くの投稿されたコードがありますが、それでもあなたのコードが最も読みやすいです。

于 2013-07-20T11:47:12.973 に答える
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)
于 2013-07-16T14:53:45.127 に答える