我的代码是:
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;
}
};
有更好的方法吗?
答案 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
,-1
,1
和2
之类的值,可能会更有用。一个三元运算符可以为你节省一些写作,但它不一定会变得更清晰。
或者,一些数学可以帮助你:
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)