Conditions multiples dans une clause if

Si j'ai une déclaration if qui doit répondre à ces exigences:

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

Y a-t-il moyen de dire que tous sont plus grands que zéro? Juste pour un code DRY plus efficace?

Quelque chose comme:

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

Vous pouvez obtenir la valeur la plus basse avec Math.min , et vous n'avez besoin que d'un contrôle contre la limite inférieure.

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

Vous pouvez utiliser un tableau avec .every . C'est moins DRY, mais plus détaillé:

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

La raison pour laquelle j'aime cela est qu'en utilisant un tableau, il devient évident que vous répétez la logique pour chaque variable. Nommer le rappel de manière évidente aide les futurs lecteurs à comprendre exactement ce que ce contrôle permettra. Et enfin, cela donne lieu à des numéros non seulement, mais à tout autre type de contrôle à l'avenir – avec une complexité cachée à l'encontre de la déclaration if elle-même.

Comme certains l'ont déclaré, il n'y a rien de mal à avoir de multiples conditions simples dans une déclaration if, mais je considérerais changer le formatage en:

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

Alternativement, je modifierais l'utilisation de ces variables comme des nombres entiers, dans des variables bool, c'est-à-dire isCave , hasTraining ou similaire, puis définissez le bool approprié plus près de l'endroit où votre code définit les différentes propriétés ( Edit: Et peut-être revenir tôt s'il est faux , Pour éviter d'autres calculs inutiles). Cela simplifiera votre déclaration if à ce dernier dans le prochain bloc de code, qui en plus montre une variante qui peut être utilisée si les conditions sont légèrement plus complexes ou que vous souhaitez faciliter la lecture de l'instruction 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 } 

En d'autres termes, les conditions multiples dans votre déclaration if ne sont pas votre plus grande odeur de code, je voudrais changer mon objectif de donner à vos variables de meilleurs noms indiquant clairement ce que la valeur indique. Cela améliorerait la lecture et la compréhension de votre code, beaucoup plus qu'une étrange syntaxe pour éviter de multiples conditions.

Il n'y a rien de mal à avoir des conditions multiples et simples dans une déclaration if . Toutefois, si elle ne peut correspondre à une seule ligne (environ 80 caractères), vous avez quelques solutions.

En fin de compte, vous ne vérifiez pas si quatre variables sont supérieures à zéro. Vous vérifiez un ensemble de conditions. Le fait que ces conditions sont ( actuellement ) représentées par des entiers signés n'est pas uniquement pertinent, mais les détails d'implémentation qui doivent être cachés dans les fonctions.

  1. Utilisez des drapeaux intermédiaires:

     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. Utilisez une fonction:

     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. Utilisez les fonctions pour les conditions individuelles que vous devez vérifier:

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

Cela ressemble à un travail pour une fonction "valideur" comme ceci:

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

Comme d'autres l'ont suggéré, vous pouvez utiliser. Tout en n'utilisant pas ES6 ou polyfills:

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

Alternativement, vous pouvez utiliser .some pour obtenir l'inverse (nécessite également ES6 ou polyfill):

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

Si vous ne souhaitez pas utiliser ES6, vous pouvez utiliser réduire:

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

En supposant des entrées de 32 bits.

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

Si l'un des numéros ci-dessus est négatif, le résultat de l'OR sera négatif et les exigences ne sont pas respectées.

Edit: cela ne fonctionne pas lorsque l'un des paramètres est 0. Cela fonctionnera, mais il ne sera pas aussi efficace et facile à lire que d'autres façons.

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

Une autre solution correcte

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

Filtrer avec lodash :

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

Il itère sur les éléments du tableau et renvoie un nouveau tableau composé des éléments qui répondent à l'exigence donnée d'être > 0 – si le tableau de résultats est de taille différente, étant donné qu'il signifie qu'un ou plusieurs de ses éléments ne sont pas > 0 .

Je l'ai spécifié spécifiquement pour vérifier chaque valeur de tableau (même s'il n'est pas nécessaire car le premier > 0 pourrait donner le même résultat) pour ne pas arrêter sur le premier positif comme vous l'avez déclaré vouloir vérifier tous.

PS Vous pouvez l'inverser pour vérifier <= 0 et vérifier pour .length === 0 instaed pour être plus rapide.

Pourquoi cherchez-vous une solution?

Votre question ressemble à une réponse optimale et simple, je la recommande. Nous avons plusieurs solutions pour cela. Au-dessous d'une est la suivante.

JSBin pour .every ()

Atteignez-le en utilisant la fonction .every

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