JavaScript fait remonter son ascendance à C et C n'a pas d'opérateur XOR logique. Principalement parce que ce n'est pas utile. Bitwise XOR est extrêmement utile, mais au cours de toutes mes années de programmation, je n'ai jamais eu besoin d'un XOR logique.
Si vous avez deux variables booléennes, vous pouvez imiter XOR avec:
if (a != b)
Avec deux variables arbitraires, vous pouvez les utiliser !
pour les contraindre à des valeurs booléennes, puis utiliser la même astuce:
if (!a != !b)
C'est assez obscur et mériterait certainement un commentaire. En effet, vous pouvez même utiliser l'opérateur XOR au niveau du bit à ce stade, bien que ce soit beaucoup trop intelligent à mon goût:
if (!a ^ !b)
!=
est que vous ne pouvez pas faire la même chose quea ^= b
, cara !== b
c'est juste l' opérateur d' inégalité stricte .Javascript a un opérateur XOR au niveau du bit: ^
Vous pouvez l'utiliser avec des booléens et il donnera le résultat sous forme de 0 ou 1 (que vous pouvez reconvertir en booléen, par exemple
result = !!(op1 ^ op2)
). Mais comme John l'a dit, c'est équivalent àresult = (op1 != op2)
, ce qui est plus clair.la source
true^true
est 0, etfalse^true
est 1.||
et&&
peut être utilisé comme opérateurs logiques sur des non-booléens (par exemple,5 || 7
renvoie une valeur de vérité,"bob" && null
renvoie une valeur de faux) mais^
ne peut pas. Par exemple,5 ^ 7
égal à 2, ce qui est vrai.(true ^ false) !== true
ce qui le rend ennuyeux avec les bibliothèques qui nécessitent des booléens réelsa ^= true
pour basculer les booléens et cela échoue sur certaines machines telles que les téléphones.Il n'y a pas de véritables opérateurs booléens logiques en Javascript (bien que cela
!
soit assez proche). Un opérateur logique ne prendrait quetrue
oufalse
comme opérandes et ne renverrait quetrue
oufalse
.En Javascript
&&
et||
prenez toutes sortes d'opérandes et retournez toutes sortes de résultats amusants (tout ce que vous leur donnez).De plus, un opérateur logique doit toujours prendre en compte les valeurs des deux opérandes.
En Javascript
&&
et||
prenez un raccourci paresseux et n'évaluez pas le deuxième opérande dans certains cas et négligez ainsi ses effets secondaires. Ce comportement est impossible à recréer avec un xor logique.a() && b()
évaluea()
et renvoie le résultat s'il est faux. Sinon, il évalueb()
et renvoie le résultat. Par conséquent, le résultat renvoyé est véridique si les deux résultats sont véridiques et faux dans le cas contraire.a() || b()
évaluea()
et renvoie le résultat s'il est véridique. Sinon, il évalueb()
et renvoie le résultat. Par conséquent, le résultat renvoyé est faux si les deux résultats sont faux et véridique dans le cas contraire.L'idée générale est donc d'évaluer d'abord l'opérande gauche. L'opérande correct n'est évalué que si nécessaire. Et la dernière valeur est le résultat. Ce résultat peut être n'importe quoi. Objets, nombres, chaînes ... peu importe!
Cela permet d'écrire des choses comme
ou
Mais la valeur de vérité de ce résultat peut également être utilisée pour décider si un opérateur logique "réel" aurait retourné vrai ou faux.
Cela permet d'écrire des choses comme
ou
Mais un opérateur xor "logique" (
^^
) devrait toujours évaluer les deux opérandes. Cela le rend différent des autres opérateurs "logiques" qui n'évaluent le deuxième opérande que si nécessaire. Je pense que c'est pourquoi il n'y a pas de xor "logique" en Javascript, pour éviter toute confusion.Alors, que devrait-il se passer si les deux opérandes sont faux? Les deux pourraient être retournés. Mais un seul peut être retourné. Laquelle? Le premier? Ou le second? Mon intuition me dit de renvoyer le premier mais généralement les opérateurs «logiques» évalués de gauche à droite et renvoyer la dernière valeur évaluée. Ou peut-être un tableau contenant les deux valeurs?
Et si un opérande est vrai et que l'autre opérande est faux, un xor doit renvoyer celui qui est vrai. Ou peut-être un tableau contenant le vrai, pour le rendre compatible avec le cas précédent?
Et enfin, que devrait-il se passer si les deux opérandes sont véridiques? Vous vous attendriez à quelque chose de faux. Mais il n'y a pas de résultats erronés. L'opération ne doit donc rien renvoyer. Alors peut
undefined
- être ou… un tableau vide? Mais un tableau vide est toujours vrai.En adoptant l'approche par tableau, vous vous retrouveriez avec des conditions telles que
if ((a ^^ b).length !== 1) {
. Très perturbant.la source
Le XOR de deux booléens est simplement de savoir s'ils sont différents, par conséquent:
la source
Convertissez les valeurs en forme booléenne puis prenez XOR au niveau du bit. Cela aidera également avec les valeurs non booléennes.
la source
Covert en booléen, puis effectuez xor comme -
la source
!!a ^ !!b
équivaut à!a ^ !b
. Des arguments pourraient être avancés pour savoir lequel est le plus facile à lire.il y a ... une sorte de:
ou plus facile à lire:
Pourquoi? sais pas.
parce que les développeurs javascript pensaient que ce serait inutile car il peut être exprimé par d'autres opérateurs logiques déjà implémentés.
vous pourriez aussi bien avoir gon avec nand et c'est tout, vous pouvez impressionner toutes les autres opérations logiques possibles à partir de cela.
Je pense personnellement que cela a des raisons historiques qui découlent des langages de syntaxe basés sur c, où, à ma connaissance, xor n'est pas présent ou du moins extrêmement rare.
la source
Oui, faites ce qui suit. En supposant que vous avez affaire aux booléens A et B, la valeur A XOR B peut être calculée en JavaScript à l'aide de ce qui suit
La ligne précédente est également équivalente à la suivante
Personnellement, je préfère xor1 car je dois taper moins de caractères. Je crois que xor1 est également plus rapide. Il s'agit simplement d'effectuer deux calculs. xor2 effectue trois calculs.
Explication visuelle ... Lisez le tableau ci-dessous (où 0 signifie faux et 1 signifie vrai) et comparez les 3e et 5e colonnes.
! (A === B):
Prendre plaisir.
la source
var xor1 = !(a === b);
est le même quevar xor1 = a !== b;
!(2 === 3)
esttrue
, mais2
et3
sont véridiques ainsi2 XOR 3
devrait l'êtrefalse
.Check-out:
Vous pouvez l'imiter quelque chose comme ceci:
la source
Que diriez-vous de transformer le résultat int en booléen avec double négation? Pas si joli, mais vraiment compact.
la source
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
Aussi, pourquoi tant de parenthèses?B = !state1 !== !state2;
Ou vous pouvez même laisser tomber la négation:B = state1 !== state2;
state1 !== state2
, alors vous n'avez pas besoin de faire de transtypage là-bas, car il!==
s'agit d'un opérateur logique, pas d'un bit.12 !== 4
est vrai'xy' !== true
est également vrai. Si vous utilisiez à la!=
place de!==
, alors vous devrez faire du casting.!==
et!=
est toujours booléen ... je ne sais pas quelle est la distinction que vous faites ici, ce n'est absolument pas le problème. Le problème est que l'opérateur XOR que nous voulons est vraiment l'expression(Boolean(state1) !== Boolean(state2))
. Pour les booléens, "xy", 12, 4 ettrue
sont toutes des valeurs de vérité et doivent être convertis entrue
. ainsi("xy" XOR true)
devrait êtrefalse
, mais("xy" !== true)
est plutôttrue
, comme vous le faites remarquer. Donc!==
ou!=
sont (les deux) équivalents à "XOR logique" si et seulement si vous convertissez leurs arguments en booléens avant d' appliquer.Dans la fonction xor ci-dessus, il en résultera un résultat SIMILAIRE car xor logique ne correspond pas exactement à xor logique, ce qui signifie qu'il en résultera "faux pour des valeurs égales" et "vrai pour différentes valeurs" avec le type de données correspondant en considération.
Cette fonction xor fonctionnera comme un xor réel ou un opérateur logique , ce qui signifie qu'il en résultera vrai ou faux selon que les valeurs de passage sont vraies ou fausses . Utiliser selon vos besoins
la source
(!!x) === (!!y)
. La différence est une conversion en booléen.'' === 0
est faux, tandis quexnor('', 0)
est vrai.Dans Typescript (le + change en valeur numérique):
Alors:
la source
!!(false ^ true)
fonctionne très bien avec les booléens. En dactylographié, + est nécessaire pour le rendre valide!!(+false ^ +true)
.cond1 xor cond2
équivaut àcond1 + cond 2 == 1
:Voici la preuve:
la source
La raison pour laquelle il n'y a pas de XOR logique (^^) est que contrairement à && et || cela ne donne aucun avantage paresseux. C'est l'état des deux expressions à droite et à gauche qui doivent être évaluées.
la source
Voici une solution alternative qui fonctionne avec plus de 2 variables et fournit un compte comme bonus.
Voici une solution plus générale pour simuler un XOR logique pour toutes les valeurs de vérité / faux, comme si vous aviez l'opérateur dans des instructions IF standard:
La raison pour laquelle j'aime cela, c'est parce qu'elle répond également "Combien de ces variables sont véridiques?", Donc je pré-stocke généralement ce résultat.
Et pour ceux qui veulent un comportement de vérification strict booléen-TRUE xor, faites simplement:
Si vous ne vous souciez pas du nombre, ou si vous vous souciez des performances optimales: utilisez simplement le xor au niveau du bit sur les valeurs forcées à booléen, pour la solution vérité / fausseté:
la source
Hé j'ai trouvé cette solution, pour faire et XOR sur JavaScript et TypeScript.
la source
Essayez ce court et facile à comprendre
Cela fonctionnera pour tout type de données
la source
true == someboolean
n'est pas nécessaire, donc vraiment, ce que vous avez fait, c'est envelopper les stricts non-égaux dans une fonction.