41 votes

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 un moyen de dire qu'ils sont tous supérieurs à zéro ? Juste pour un code DRY plus efficace ?

Quelque chose comme :

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

1 votes

Il y avait une bonne réponse si ces valeurs ne peuvent être que 0 ou positives (jamais négatives, ou jamais TRES TRES grandes)

0 votes

@JaromandaX j'ai pensé à ça aussi !

3 votes

Quel est le problème avec if (cave && training && mobility && sleep) ?

46voto

RilezG Points 448

Vous pourriez obtenir la valeur la plus basse avec Math.min et vous n'avez alors besoin que d'une seule vérification de la borne inférieure.

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

3 votes

Très propre et facile à comprendre.

83 votes

C'est pourquoi un code simple, intelligent, concis et propre n'est pas nécessairement un bon code. Le code est une question d'intention. Si je rencontre ce problème, je devrai passer du temps à essayer de comprendre 1) ce que ce code fait, et 2) pourquoi c'est écrit comme ça. Au final, je serai énervé, je rétablirai vos modifications et je m'assurerai que vous ayez des revues de code obligatoires pour l'année prochaine.

11 votes

@RilezG Nous analysons les instructions if avec des conditions simples tout le temps, tous les jours. Cela ne demande que peu ou pas d'effort. Ce n'est pas un idiome. Il faut l'analyser, le comprendre et l'apprendre. Et pour quoi faire ?

34voto

RGraham Points 15305

Vous pouvez utiliser un tableau avec .tous . C'est moins DRY, mais plus verbeux :

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

La raison pour laquelle j'aime cette méthode est qu'en utilisant un tableau, il devient évident que vous répétez la logique pour chaque variable. Nommer le callback de manière évidente aide les futurs lecteurs à comprendre exactement ce que cette vérification va réaliser. Enfin, cela permet d'envisager non seulement des nombres, mais aussi n'importe quelle vérification de n'importe quel type à l'avenir - toute complexité étant cachée dans la fonction de rappel. if La déclaration elle-même.

0 votes

Vous pouvez également utiliser some

0 votes

Tous les tableaux de l'instruction if doivent être du même type, n'est-ce pas ? String o Integer et ainsi de suite.

1 votes

@Alex Polyfill est sur la page liée. Non. Aucune vérification de type n'est effectuée ici. Cela pourrait être ajouté dans la fonction d'aide si nécessaire.

29voto

holroy Points 667

Comme certains l'ont dit, il n'y a rien de mal à avoir de multiples conditions simples dans une instruction if, mais j'envisagerais de modifier la mise en forme en :

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

Alternativement, je changerais l'utilisation de ces variables en tant qu'entiers, en 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 ( Editar: Et éventuellement, retour anticipé si c'est faux, pour éviter d'autres calculs inutiles). Cela simplifierait votre instruction if par rapport à celle du bloc de code suivant, qui présente en outre une variante pouvant être utilisée si les conditions deviennent légèrement plus complexes ou si 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 me concentrerais sur le fait 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, bien plus qu'une syntaxe étrange pour éviter les conditions multiples.

8voto

isanae Points 973

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

En définitive, 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 soient ( actuellement ) représentés par des entiers signés n'est non seulement pas pertinent, mais constitue un détail d'implémentation qui devrait être caché 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())
        // ...

1 votes

S'il vous plaît, faites-en une simple var valid_status = (mobility > 0 && sleep > 0);

0 votes

@Bergi J'avais en fait écrit quelque chose, que j'ai supprimé. Je pensais que les gens comprendraient qu'une expression booléenne pouvait être utilisée, à moins qu'elle ne soit trop difficile à lire ou qu'elle comporte trop de conditions. Les programmeurs expérimentés le sauraient, et je ne voudrais pas que les novices pensent qu'il est bon de faire tenir tout ça dans une seule ligne. Donc non, je ne vais probablement pas le changer.

1 votes

Que voulez-vous dire par "faire tenir tout ça dans une ligne" ? Peu importe que l'expression soit dans une affectation ou une condition if, il s'agit toujours d'une "ligne". Utilisation de if / else pour définir des variables booléennes est tout simplement une mauvaise pratique, surtout pour les programmeurs novices.

4voto

Lưu Vĩnh Phúc Points 3183

En supposant des ints de 32 bits.

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

Si l'un des nombres ci-dessus est négatif, le résultat du OU sera négatif et les conditions ne sont pas remplies.

Edit : c'est équivalent à if(cave >= 0 && training >= 0 && mobility >= 0 && sleep >= 0) et ne le fera pas lorsque certains des paramètres sont à 0. La solution consiste à inverser le bit de signe :

if ((~cave | ~training | ~mobility | ~sleep) <= 0)

Quelques méthodes alternatives qui fonctionnent même pour les valeurs à virgule flottante

if (cave*training*mobility*sleep > 0)
if (Math.sign(cave) * Math.sign(training) * Math.sign(mobility) * Math.sign(sleep) > 0)
if (Math.sign(cave) | Math.sign(training) | Math.sign(mobility) | Math.sign(sleep) > 0)

0 votes

Vous avez raison, c'est la bonne façon de faire, et elle devrait être marquée comme la bonne réponse.

0 votes

Notez que cela ne s'applique pas à tout autre cas qui n'est pas un cas d'espèce. 0 un travail intelligent néanmoins

4 votes

Si cave est égal à 0 et le reste des variables sont positives, alors le résultat de l'équation OR La déclaration sera positive. Mais ce n'est pas le résultat souhaité ; il renvoie le résultat inverse du code de l'OP.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X