9
votes

Vérifiez exactement une option booléenne ensemble

Eh bien, c'est une sorte de hacky: xxx

est-il un meilleur moyen de le faire en JavaScript? En utilisant l'un des

  • Handling booléen / numérique plus intelligent
  • Array Sneaky ou Opérations fonctionnelles

    et ainsi de suite. Solutions JavaScript et Node Bienvenue.

    Dans mon problème actuel, les options proviennent du commandant du module de noeud, donc je ne traite pas de véritables choses booléennes, de vraies et de fausseté. Il peut y avoir une solution de commandant aussi.


6 commentaires

Quel est le cas d'utilisation que vous résolvez? Validez-vous la saisie de l'utilisateur? Si oui, pouvez-vous utiliser des boutons radio?


@Chadcook Ceci est le côté serveur. Il commande à partir de node.js commandant. Dans mon problème réel, il est par défaut de OPT3 donc je vérifie réellement > 1 .


Comment exécutez-vous le côté du serveur JavaScript?


@Chadcook nœud.js


(vrai + faux === 1). Boolean automaticaly sera converti en int


@DMITRYTEPLYAKOV Oui, nécessaire pour que les valeurs soient également booléennes utilisent également !! .


6 Réponses :


6
votes

Vous pouvez le faire: xxx

Ça fonctionne car

  • !! fait un booléen à partir de n'importe quelle valeur ( true si les objets évaluent comme true dans si (valeur) )
  • Lorsque vous ajoutez des booléens, vous obtenez 1 pour true et 0 pour false . .

5 commentaires

S'il sait qu'ils sont booléens, le !! est inutile, vous pouvez donc changer cela en si (Opt1 + Opt2 + Opt3! = 1) {}


@spudly je ne sais pas si les valeurs sont booléennes. Ce n'était pas clair dans la question.


Ils ne sont en aucun cas, en tout cas, il s'agit du moyen le plus sûr d'aller.


Moins lisible, mais vous pouvez simplifier l'expression à: ! Opt1 +! Opt2 +! Opt3 === 2 (2 est le nombre d'options, 3, moins l'option de véracité).


@Paulpro oui, c'est vrai, mais je ne pense pas que ça vaut la peine. L'écart sémantique avec le but est trop large à mon avis.



11
votes

En supposant que vous aviez un éventail d'options, vous pouvez faire:

var opt = 'a'; // (or 'b', or 'c')


4 commentaires

Pourquoi même la peine de passer une fonction anonyme? Il suffit d'utiliser si (opts.filter (booléen) .length! == 1) {} . Ou même avec votre fonction anonyme, il est plus logique de simplement retourner v


Merci pour la suggestion d'utiliser simplement la fonction booléenne. N'avait pas pensé à cela, et c'est une forte amélioration. En ce qui concerne simplement le V, je l'ai codé comme ça d'abord, mais l'a changé parce que l'Asker n'était pas certain que les valeurs seraient effectivement des booléens en premier lieu.


Aucun problème! Et oui, si c'est quelque chose de simple comme ça, j'essaie de penser à une façon de passer une fonction intégrée au lieu d'une personnalisation. Eh bien pour le retour v , il fonctionne - la valeur renvoyée à partir du rappel passé sur Filtre est évalué comme Truthy , pas vrai , donc peu importe si le contenu est des booléens. Donc, par exemple, si vous venez de retour v; , "" ne passera pas, tandis que "A" sera. En utilisant booléen techniquement la même chose, juste plus tôt


Brillant, @spudly! J'aimerais avoir pensé à cela.



1
votes

Je pense que vous êtes trop intelligent, qu'est-ce qui ne va pas avec: XXX PRE>

Bien sûr, je peux aussi jouer le jeu intelligent aussi: P>

 if( opts.filter(Boolean).length !== 1 ) {
     throw new Error("Exactly one option must be set");
 }


3 commentaires

JavaScript a beaucoup de modèles bien acceptés qui vous permettent de faire dans une ligne de code lisible que faudrait 8. Je préfère les modèles "intelligents" quand ils sont bien compris (et donc pas intelligents). Je suis assez novice en JavaScript, alors je ne le connais pas encore.


Pour des exemples de solutions "intelligentes", voir toutes les autres réponses.


Aurait dû donner à l'intelligent avant, les gens sont incontournables.



1
votes

Vous avez mentionné dans votre commentaire selon lequel cela provient d'un objet Options de commandant.

Vous pouvez le faire plus élégamment à l'aide de Lodash : p> xxx pré>

Si vous souhaitez uniquement compter un sous-ensemble des options, vous pouvez insérer P>

.pick('a', 'b', 'c')


1 commentaires

Ah, c'est comme ça que vous utilisez Lodash.



1
votes
if ([opt1, opt2, opt3].reduce(function(x, y) { return x + !!y }, 0) == 1) {
    // exactly one
};
ECMAScript 5 reduce function.

0 commentaires

0
votes

@spudly est sur la bonne voie, mais cela pourrait être un peu plus compact: xxx

voir méthode de filtre ES5 pour plus d'informations.


0 commentaires