if子句中的多个条件

时间:2021-05-20 23:10:16

If I have an if statement that needs to meet these requirements:

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

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

Is there any way to say that all of them are bigger than zero? Just for more efficient DRY code?

有没有办法说它们都大于零?只是为了更有效的DRY代码?

Something like:

就像是:

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

9 个解决方案

#1


47  

You could get the lowest value with Math.min, and then you only need one check against the lower bound.

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

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

#2


34  

You could use an array with .every. This is less DRY, but more verbose:

你可以使用.every的数组。这不是干,但更冗长:

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

The reason I like this is that by using an array, it becomes apparent that you're repeating logic for every variable. Naming the callback in an obvious manner helps future readers understand exactly what that check will achieve. And finally, this gives scope for not just numbers, but any check of any type in the future - with any complexity hidden away from the if statement itself.

我喜欢这个的原因是通过使用数组,很明显你正在为每个变量重复逻辑。以明显的方式命名回调有助于未来的读者准确理解该检查将实现什么。最后,这不仅为数字提供了范围,而且还为未来任何类型的任何检查提供了范围 - 任何复杂性都隐藏在if语句本身之外。

#3


29  

As some have stated there is nothing wrong in having multiple simple conditions in an if statement, however I would consider changing the formatting into:

正如一些人所说,在if语句中有多个简单条件没有任何问题,但我会考虑将格式更改为:

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

Alternatively I would change the from using these variables as integers, into bool variables, i.e. isCave, hasTraining, or similar, and then set the proper bool closer to where your code defines the different properties (Edit: And possibly return early if it is false, to prevent further unneccessary calculations). This would simplify your if statement to the latter in the next code block, which in addition shows a variant which can be used if the conditions becomes slightly more complex or you would like to ease the reading of the if statement:

或者,我会将使用这些变量作为整数更改为bool变量,即isCave,hasTraining或类似变量,然后将正确的bool设置为更靠近代码定义不同属性的位置(编辑:如果它是假的,可能会提前返回) ,以防止进一步不必要的计算)。这将在下一个代码块中简化你对if语句的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
}

In other words, the multiple conditions in your if statement is not your biggest code smell, I would shift my focus to giving your variables better names clearly indicating what the value indicates. This would improve reading and understanding of your code, way more than some strange syntax to avoid multiple if conditions.

换句话说,你的if语句中的多个条件不是你最大的代码味道,我会把注意力转移到给你的变量更好的名字,清楚地表明值表示什么。这样可以提高对代码的阅读和理解,比一些奇怪的语法更能避免多条if条件。

#4


8  

There is nothing wrong with having multiple, simple conditions in an if statement. However, if it cannot fit into a single line (about 80 characters), you have a few solutions.

在if语句中使用多个简单条件没有任何问题。但是,如果它不能放入一行(大约80个字符),那么您有一些解决方案。

Ultimately, you are not checking whether four variables are greater than zero. You are checking for a set of conditions. The fact that these conditions are (currently) represented by signed integers is not only irrelevant, but is an implementation details that should be hidden away in functions.

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

  1. Use intermediary flags:

    使用中间标志:

    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. Use a 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. Use functions for the individual conditions you need to check:

    使用函数来检查您需要检查的各个条件:

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

#5


4  

Sounds like a job for a "validator" function like this:

听起来像这样的“验证器”功能的工作:

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)) {
    // ...
}

#6


4  

As others have suggested, you can use .every if you don't mind using ES6 or polyfills:

正如其他人所建议的那样,如果你不介意使用ES6或polyfill,你可以使用.every:

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

if (hasAllStats) { }

Alternatively, you can use .some to get the inverse (Also requires ES6 or polyfill):

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

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

if (!isMissingStats) { }

If you don't want to use ES6, you can use reduce:

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

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

if (hasAllStats) { }

#7


4  

Assuming 32-bit ints.

假设32位整数。

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

If any of the above numbers are negative, the result of the OR will be negative and the requirements aren't met.

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

Edit: it doesn't work when either of the parameters are 0. This will work but it won't be as efficient and easy to read like other ways.

编辑:当任一参数为0时,它不起作用。这将起作用,但它不会像其他方式那样高效和易于阅读。

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

Another better fix

另一个更好的解决

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

#8


2  

Filter it with lodash:

用lodash过滤它:

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

console.log(result);

It iterates over array elements and returns new array composed of those elements that meet given requirement of being > 0 - if result array is different size than given one it means one or more of it's elements were not > 0.

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

I wrote it specifically to check every array value (even if not necessary as first > 0 could give same result) to not stop on first positive as you stated you want to check all of them.

我专门写了它来检查每个数组值(即使没有必要,因为第一个> 0可以给出相同的结果)不要停在第一个正数上,因为你声明要检查所有数组。

PS You can reverse it to check for <= 0 and check for .length === 0 instaed to be faster.

PS您可以将其反转以检查<= 0并检查.length === 0 instaed更快。

#9


1  

Why you are looking for solution?

为什么要寻找解决方案?

Your question looks like best and simple answer, i recommend it. We have multiple solutions for this. Below one is that.

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

JSBin for .every()

JSBin for .every()

Achieve it by using .every function

通过使用.every函数实现它

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

if(flag) {
  alert('All the elements are greater than Zero');
}

#1


47  

You could get the lowest value with Math.min, and then you only need one check against the lower bound.

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

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

#2


34  

You could use an array with .every. This is less DRY, but more verbose:

你可以使用.every的数组。这不是干,但更冗长:

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

The reason I like this is that by using an array, it becomes apparent that you're repeating logic for every variable. Naming the callback in an obvious manner helps future readers understand exactly what that check will achieve. And finally, this gives scope for not just numbers, but any check of any type in the future - with any complexity hidden away from the if statement itself.

我喜欢这个的原因是通过使用数组,很明显你正在为每个变量重复逻辑。以明显的方式命名回调有助于未来的读者准确理解该检查将实现什么。最后,这不仅为数字提供了范围,而且还为未来任何类型的任何检查提供了范围 - 任何复杂性都隐藏在if语句本身之外。

#3


29  

As some have stated there is nothing wrong in having multiple simple conditions in an if statement, however I would consider changing the formatting into:

正如一些人所说,在if语句中有多个简单条件没有任何问题,但我会考虑将格式更改为:

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

Alternatively I would change the from using these variables as integers, into bool variables, i.e. isCave, hasTraining, or similar, and then set the proper bool closer to where your code defines the different properties (Edit: And possibly return early if it is false, to prevent further unneccessary calculations). This would simplify your if statement to the latter in the next code block, which in addition shows a variant which can be used if the conditions becomes slightly more complex or you would like to ease the reading of the if statement:

或者,我会将使用这些变量作为整数更改为bool变量,即isCave,hasTraining或类似变量,然后将正确的bool设置为更靠近代码定义不同属性的位置(编辑:如果它是假的,可能会提前返回) ,以防止进一步不必要的计算)。这将在下一个代码块中简化你对if语句的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
}

In other words, the multiple conditions in your if statement is not your biggest code smell, I would shift my focus to giving your variables better names clearly indicating what the value indicates. This would improve reading and understanding of your code, way more than some strange syntax to avoid multiple if conditions.

换句话说,你的if语句中的多个条件不是你最大的代码味道,我会把注意力转移到给你的变量更好的名字,清楚地表明值表示什么。这样可以提高对代码的阅读和理解,比一些奇怪的语法更能避免多条if条件。

#4


8  

There is nothing wrong with having multiple, simple conditions in an if statement. However, if it cannot fit into a single line (about 80 characters), you have a few solutions.

在if语句中使用多个简单条件没有任何问题。但是,如果它不能放入一行(大约80个字符),那么您有一些解决方案。

Ultimately, you are not checking whether four variables are greater than zero. You are checking for a set of conditions. The fact that these conditions are (currently) represented by signed integers is not only irrelevant, but is an implementation details that should be hidden away in functions.

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

  1. Use intermediary flags:

    使用中间标志:

    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. Use a 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. Use functions for the individual conditions you need to check:

    使用函数来检查您需要检查的各个条件:

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

#5


4  

Sounds like a job for a "validator" function like this:

听起来像这样的“验证器”功能的工作:

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)) {
    // ...
}

#6


4  

As others have suggested, you can use .every if you don't mind using ES6 or polyfills:

正如其他人所建议的那样,如果你不介意使用ES6或polyfill,你可以使用.every:

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

if (hasAllStats) { }

Alternatively, you can use .some to get the inverse (Also requires ES6 or polyfill):

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

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

if (!isMissingStats) { }

If you don't want to use ES6, you can use reduce:

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

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

if (hasAllStats) { }

#7


4  

Assuming 32-bit ints.

假设32位整数。

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

If any of the above numbers are negative, the result of the OR will be negative and the requirements aren't met.

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

Edit: it doesn't work when either of the parameters are 0. This will work but it won't be as efficient and easy to read like other ways.

编辑:当任一参数为0时,它不起作用。这将起作用,但它不会像其他方式那样高效和易于阅读。

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

Another better fix

另一个更好的解决

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

#8


2  

Filter it with lodash:

用lodash过滤它:

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

console.log(result);

It iterates over array elements and returns new array composed of those elements that meet given requirement of being > 0 - if result array is different size than given one it means one or more of it's elements were not > 0.

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

I wrote it specifically to check every array value (even if not necessary as first > 0 could give same result) to not stop on first positive as you stated you want to check all of them.

我专门写了它来检查每个数组值(即使没有必要,因为第一个> 0可以给出相同的结果)不要停在第一个正数上,因为你声明要检查所有数组。

PS You can reverse it to check for <= 0 and check for .length === 0 instaed to be faster.

PS您可以将其反转以检查<= 0并检查.length === 0 instaed更快。

#9


1  

Why you are looking for solution?

为什么要寻找解决方案?

Your question looks like best and simple answer, i recommend it. We have multiple solutions for this. Below one is that.

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

JSBin for .every()

JSBin for .every()

Achieve it by using .every function

通过使用.every函数实现它

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

if(flag) {
  alert('All the elements are greater than Zero');
}