if条件中的多个条件

如果我有一个if语句需要满足这些要求:

if(cave > 0 && training > 0 && mobility > 0 && sleep > 0) 

有什么方法可以说,他们都大于零? 只是为了更有效的干代码?

就像是:

 if(cave, training, mobility, sleep > 0) 

你可以用Math.min得到最低的值,然后你只需要对下限进行一次检查。

 if(Math.min(cave, training, mobility, sleep) > 0) { //do something } 

你可以使用.every数组。 这是干的less,但更详细:

 var isGreaterThanZero = function(val) { return val > 0; }; if([cave, training, mobility, sleep].every(isGreaterThanZero)) { // Do Something } 

我喜欢这个的原因是通过使用一个数组,显然你正在为每个variables重复逻辑。 以明显的方式命名callback可以帮助未来的读者准确理解检查的内容。 最后,这不仅为数字提供了范围,而且在未来对任何types的任何检查都有了范围 – 复杂性远远超出if语句本身。

正如有些人所说,在if语句中有多个简单的条件没有什么不对,但是我会考虑将格式更改为:

 if ( cave > 0 && training > 0 && mobility > 0 && sleep > 0 ) 

或者我会改变使用这些variables作为整数,变成布尔variables,即isCavehasTraining ,或类似,然后设置适当的布尔更接近你的代码定义不同的属性( 编辑:如果是假,以防止进一步的不必要的计算)。 这将在下一个代码块中简化对后者的if语句,此外,如果条件稍微复杂一些,或者您想要简化if语句的读取,则会显示一个可以使用的变体:

 var isCave = cave > 0; # What does cave > 0 mean? var hasTraining = training > 0; var isMobile = mobility > 0; var isNotSleeping = sleep > 0; # What does sleep > 0 indicate? Unclear if (isCave && hasTraining && isMobile && isNotSleeping ) { // Do your thing } 

换句话说,if语句中的多个条件并不是你最大的代码味道,我将把焦点转移到给你的variables更好的名字上,清楚地指出这个值的含义。 这样可以提高对代码的阅读和理解,而不仅仅是一些奇怪的语法,以避免多个条件。

if语句中有多个简单的条件没有任何问题。 但是,如果它不能适合一行(大约80个字符),你有几个解决scheme。

最终,你不检查四个variables是否大于零。 您正在检查一组条件。 这些条件( 当前 )由有符号整数表示的事实不仅是不相关的,而且是应该隐藏在函数中的实现细节。

  1. 使用中间标志:

     var valid_location = false; if (cave > 0 && training > 0) valid_location = true; var valid_status = false; if (mobility > 0 && sleep > 0) valid_status = true; if (valid_location && valid_status) // ... 
  2. 使用function:

     function can_do_this() { // split conditions into logical groups // checking location, because you need training if you're // in a cave if (cave <= 0 || training <= 0) return false; // checking status, because you have to be mobile and // sleepy if (mobility <= 0 || sleep <= 0) return false; return true; } if (can_do_this()) // ... 
  3. 使用您需要检查的个别条件的function:

     function valid_location() { return (cave > 0 && training > 0); } function valid_status() { return (mobility > 0 && sleep > 0); } if (valid_location() && valid_status()) // ... 

听起来像一个像这样的“validation器”function的工作:

 function areAllGreaterThanZero(){ //TODO: check inputs var result = true; [].splice.apply(arguments).forEach(function(x){ result = result && (x > 0); }); return result; } if(areAllGreaterThanZero(cave, training, mobility, sleep)) { // ... } 

正如其他人所build议的那样,如果您不介意使用ES6或polyfills,则可以使用.every:

 var hasAllStats = [cave, training, mobility, sleep] .every(function(stat) { return stat > 0; }); if (hasAllStats) { } 

或者,您可以使用.some来获得反转(也需要ES6或polyfill):

 var isMissingStats = [cave, training, mobility, sleep] .some(function(stat) { return stat <= 0; }); if (!isMissingStats) { } 

如果你不想使用ES6,你可以使用reduce:

 var hasAllStats = [cave, training, mobility, sleep] .reduce(function(hasAllStats, stat) { return hasAllStats && stat > 0; }, true); if (hasAllStats) { } 

假设32位整数。

 if ((cave | training | mobility | sleep) > 0) 

如果上述任何一个数字是负数,则OR的结果将是负数,并且不符合要求。

编辑:当任何一个参数都是0时,它不起作用。这将起作用,但不会像其他方式那样高效且容易阅读。

 if (((cave | training | mobility | sleep) > 0) && (cave*training*mobility*sleep != 0)) 

另一个更好的修复

 if (!((cave | training | mobility | sleep) < 0)) 

用lodash过滤:

 var data = [cave, training, mobility, sleep]; var result = _.filter(data, function (datum) { return datum > 0; }).length === data.length; console.log(result); 

它对数组元素进行迭代,并返回由满足给定要求> 0的那些元素组成的新数组。如果结果数组的大小不同于给定的大小,则意味着它的一个或多个元素不是> 0

我特地写了它来检查每个数组的值(即使没有必要,因为第一个> 0可能会给出相同的结果)不停止在第一个积极的,因为你说你想检查所有这些。

PS你可以反转它来检查<= 0并检查.length === 0 instaed更快。

为什么你正在寻找解决scheme?

你的问题看起来像最好和简单的答案,我推荐它。 我们有多种解决scheme。 下面是一个。

JSBin for .every()

通过使用.everyfunction来实现

 var flag = [cave, training, mobility, sleep].every(function(val) { return val > 0; }); if(flag) { alert('All the elements are greater than Zero'); }