Je veux basculer une variable entre 0 et 1. Si c'est 0 je veux la mettre à 1, sinon si c'est 1 je veux la mettre à 0.
C'est une opération tellement fondamentale que j'écris si souvent que j'aimerais étudier la manière la plus courte et la plus claire possible de le faire. Voici mon meilleur jusqu'à présent:
v = (v == 0 ? 1 : 0);
Pouvez-vous améliorer cela?
Edit: la question est de savoir comment écrire la déclaration ci-dessus dans le moins de caractères tout en conservant la clarté - comment est-ce que «ce n'est pas une vraie question»? Ce n'était pas censé être un exercice de code-golf, bien que des réponses intéressantes soient venues de personnes qui l'approchent comme du golf - c'est agréable de voir le golf utilisé de manière constructive et suscitant la réflexion.
la source
v = +!v;
Réponses:
Vous pouvez simplement utiliser:
Cela suppose bien sûr que la variable est correctement initialisée, c'est-à-dire qu'elle n'a que la valeur 0 ou 1.
Une autre méthode plus courte mais utilisant un opérateur moins courant:
Éditer:
Pour être clair; Je n'ai jamais abordé cette question comme du golf de code, juste pour trouver un moyen court de faire la tâche sans utiliser de trucs obscurs comme les effets secondaires des opérateurs.
la source
v ^= 1
clair devrait arrêter la programmation est un peu dur je pense. Comme indiqué précédemment, ce n'est pas l'un des opérateurs les plus courants et il ne fait pas la même chose quev = v ^ 1
. L'opérateur signifie également quelque chose de complètement différent dans différentes langues (VB). Oui, une recherche rapide vous dira que c'est un opérateur XOR et vous comprendrez ce que cela fait, mais pour beaucoup, cela peut ne pas être évident à première vue. Je ne pense pas que cela signifie que vous devez quitter votre emploi.Puisque
0
est unefalse
valeur et1
est unetrue
valeur.Si vous êtes heureux d'utiliser
true
etfalse
au lieu de chiffresou s'ils doivent être des nombres:
la source
+
avant ça!
. Ohhh ça a l'air tellement sale! mais cool: pswitch(v){ case 0 ...
ou si (v == 0) ou si v === 0. Vous modifiez son résultat en plus de son approche ....({v :+! v}).v
.+
signe magique ! ¯ \ _ (ツ) _ / ¯v = (v ? 0 : 1)
un JS aussi clair et idiomatique.v = (v + 1) % 2
et si vous avez besoin de parcourir plusieurs valeurs, changez simplement2
pour(n + 1)
. Supposons que vous ayez besoin de faire le cycle 0,1,2v = (v + 1) % 3
.la source
const
variable à la place des nombres magiques 2, 3, ...++v % 3
si vous voulez parcourir 0, 1, 2Vous pouvez écrire une fonction pour elle et l'utiliser comme:
v = inv(v)
la source
inv
fonction: P)inv
un nom descriptif?Si vous ne vous souciez d'aucune autre possibilité que 1:
Dans le cas ci-dessus, v finira par être 1 si v est 0, faux, non défini ou nul. Faites attention en utilisant ce type d'approche - v sera 0 même si v est "bonjour le monde".
la source
v = v ? 0 : 1
.Des lignes comme
v = 1 - v
, ouv ^= 1
ouv= +!v
feront tout le travail, mais elles constituent ce que j'appellerais des hacks. Ce ne sont pas de belles lignes de code, mais des astuces bon marché pour avoir l'effet escompté.1 - v
ne communique pas "basculer la valeur entre 0 et 1". Cela rend votre code moins expressif et introduit un endroit (quoique petit) où un autre développeur devra analyser votre code.A la place, une fonction telle que
v = toggle(v)
communique l'intention du premier coup d'œil.la source
v=1-v
ne communique pas la bascule?1-v
peut communiquer en effet basculer, mais c'est que la seule chose qu'il communique. Par exemple, il peut également communiquer une ligne avec zéro àv=1
ou une transformation en miroir centrée surv=0.5
. En ce sens, il est relativement ambigu. Il est vrai que le fait de savoir quev
cela ne peut qu'être0
ou1
limite sa signification, mais cela oblige les autres développeurs (ou votre futur soi) à comprendre ce contexte avant de pouvoir comprendre cette simple ligne. Vous ne pouvez pas être beaucoup plus clair quev = toggle(v)
v ^= 1
est parfaitement clair si vous comprenez les opérations logiques, ce que vous feriez mieux si vous êtes programmeur. Je pense que c'est la différence entre cela etv=1-v
; l'une est une opération logique et l'autre une opération arithmétique, et nous essayons de représenter un concept logique et non mathématique.v ^= 1
une certaine ambiguïté, car il peut être interprété comme un bit-xor.( L'honnêteté et l'intégrité mathématique - étant donné le nombre de votes sur cette "réponse" - m'ont amené à modifier cette réponse. toute explication semblait contraire à l'objectif. Cependant, les commentaires indiquent clairement que je devrais être clair pour éviter tout malentendu. )
Ma réponse originale:
Le libellé de cette partie de la spécification:
implique que la solution la plus précise est:
Tout d' abord, la confession: je ne reçois mes fonctions delta confus. Le delta de Kronecker aurait été légèrement plus approprié, mais pas autant que je voulais quelque chose qui était indépendant du domaine (le delta de Kronecker est principalement utilisé uniquement pour les entiers). Mais je n'aurais vraiment pas dû utiliser les fonctions delta du tout, j'aurais dû dire:
Permettez-moi de clarifier. Rappelons que la fonction est une triple, (X, Y, f) , où X et Y sont des ensembles (appelés le domaine et codomaine respectivement) et f est une règle qui attribue un élément de Y à chaque élément de X . Nous écrivons souvent le triple (X, Y, f) comme f: X → Y . Étant donné un sous-ensemble de X , disons A , il existe une fonction caractéristique qui est une fonction χ A : X → {0,1}(il peut également être considéré comme une fonction d'un plus grand codomaine tel que ℕ ou ℝ). Cette fonction est définie par la règle:
χ A (x) = 1 si x ∈ A et χ A (x) = 0 si x ∉ A .
Si vous aimez les tables de vérité, c'est la table de vérité pour la question "L'élément x de X est-il un élément du sous-ensemble A ?".
Donc, d'après cette définition, il est clair que la fonction caractéristique est ce qui est nécessaire ici, avec X un grand ensemble contenant 0 et A = {0} . Voilà ce que j'aurais dû écrire.
Et donc aux fonctions delta. Pour cela, nous devons connaître l'intégration. Soit vous le savez déjà, soit vous ne le savez pas. Si vous ne le faites pas, rien de ce que je peux dire ici ne vous dira les subtilités de la théorie, mais je peux donner un résumé d'une phrase. Une mesure sur un ensemble X est par essence "celle qui est nécessaire pour que les moyennes fonctionnent". C'est-à-dire que si nous avons un ensemble X et une mesure μ sur cet ensemble alors il y a une classe de fonctions X → ℝ , appelées fonctions mesurables pour lesquelles l'expression ∫ X f dμ a un sens et est, dans un sens vague, la « moyenne » de f sur X .
Étant donné une mesure sur un ensemble, on peut définir une "mesure" pour des sous-ensembles de cet ensemble. Cela se fait en affectant à un sous-ensemble l'intégrale de sa fonction caractéristique (en supposant qu'il s'agit d'une fonction mesurable). Cela peut être infini ou indéfini (les deux sont subtilement différents).
Il existe de nombreuses mesures, mais deux sont importantes ici. L'un est la mesure standard sur la droite réelle, ℝ. Pour cette mesure, alors ∫ ℝ f dμ est à peu près ce qu'on vous enseigne à l'école (le calcul est-il toujours enseigné dans les écoles?): Résumez de petits rectangles et prenez des largeurs de plus en plus petites. Dans cette mesure, la mesure d'un intervalle est sa largeur. La mesure d'un point est 0.
Une autre mesure importante, qui fonctionne sur n'importe quel ensemble, est appelée la mesure ponctuelle . Elle est définie de telle sorte que l'intégrale d'une fonction soit la somme de ses valeurs:
∫ X f dμ = ∑ x ∈X f (x)
Cette mesure attribue à chaque ensemble singleton la mesure 1. Cela signifie qu'un sous-ensemble a une mesure finie si et seulement s'il est lui-même fini. Et très peu de fonctions ont une intégrale finie. Si une fonction a une intégrale finie, elle doit être non nulle uniquement sur un nombre dénombrable de points. Ainsi, la grande majorité des fonctions que vous connaissez probablement n'ont pas d'intégrale finie dans le cadre de cette mesure.
Et maintenant aux fonctions delta. Prenons une définition très large. Nous avons un espace mesurable (X, μ) (donc c'est un ensemble avec une mesure sur elle) et un élément a ∈ X . Nous «définissons» la fonction delta (en fonction de a ) comme étant la «fonction» δ a : X → ℝ avec la propriété que δ a (x) = 0 si x ≠ a et ∫ X δ a dμ = 1 .
Le fait le plus important à ce sujet est le suivant: La fonction delta n'a pas besoin d'être une fonction . Elle n'est pas correctement définie: je n'ai pas dit ce qu'est δ a (a) .
Ce que vous faites à ce stade dépend de qui vous êtes. Le monde ici se divise en deux catégories. Si vous êtes mathématicien, vous dites ce qui suit:
Si vous n'êtes pas mathématicien, vous dites ce qui suit:
Ayant maintenant offensé mon public, je vais continuer.
Le delta dirac est généralement considéré comme la fonction delta d'un point (souvent 0) dans la ligne réelle avec sa mesure standard. Donc, ceux qui se plaignent dans les commentaires que je ne connais pas mes deltas le font parce qu'ils utilisent cette définition. Pour eux, je m'excuse: bien que je puisse y échapper en utilisant la défense du mathématicien (telle que popularisée par Humpty Dumpty : redéfinissez simplement tout pour que ce soit correct), c'est une mauvaise forme d'utiliser un terme standard pour signifier quelque chose de différent.
Mais il y a une fonction delta qui fait ce que je veux et c'est ce dont j'ai besoin ici. Si je prends une mesure ponctuelle sur un ensemble X alors il y a une véritable fonction δ a : X → ℝ qui satisfait les critères d'une fonction delta. En effet, nous recherchons une fonction X → ℝ qui est nulle sauf en a et telle que la somme de toutes ses valeurs soit 1. Une telle fonction est simple: la seule information manquante est sa valeur en a , et pour que la somme soit 1, il suffit de lui attribuer la valeur 1. Ce n'est autre que la fonction caractéristique sur {a} . Alors:
∫ X δ a dμ = ∑ x ∈ X δ a (x) = δ a (a) = 1.
Donc dans ce cas, pour un ensemble singleton, la fonction caractéristique et la fonction delta s'accordent.
En conclusion, il existe ici trois familles de "fonctions":
Le second d'entre eux est le plus général car l'un des autres en est un exemple lors de l'utilisation de la mesure ponctuelle. Mais le premier et le troisième ont l'avantage d'être toujours de véritables fonctions. Le troisième est en fait un cas particulier du premier, pour une famille particulière de domaines (entiers, ou un sous-ensemble de ceux-ci).
Alors, enfin, quand je l' origine écrit la réponse que je n'étais pas pensé correctement (je n'irais pas jusqu'à dire que je confus , comme je l' espère , je viens démontrais je ne sais de quoi je parle quand En fait, je pense d'abord, je ne pensais pas beaucoup). Le sens habituel du delta dirac n'est pas ce que l'on veut ici, mais l'un des points de ma réponse était que le domaine d'entrée n'était pas défini, de sorte que le delta Kronecker n'aurait pas non plus eu raison. Ainsi, la meilleure réponse mathématique (que je visais) aurait été la fonction caractéristique .
J'espère que tout cela est clair; et j'espère aussi que je n'aurai plus jamais à écrire un morceau mathématique en utilisant des entités HTML au lieu des macros TeX!
la source
Vous pourriez faire
La décrémentation définit la valeur sur 0 ou -1, puis la
Math.abs
conversion -1 sur +1.la source
v = Math.round(Math.sin(Math.PI/(v+3)));
v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));
: Dv = 1
alorsv = Math.Abs(-1)
qui est +1. Siv = 0
alorsv = Math.Abs(-0)
ce qui est 0.en général, chaque fois que vous devez basculer entre deux valeurs, vous pouvez simplement soustraire la valeur actuelle de la somme des deux valeurs de basculement:
la source
v
devient corrompu, il commencera soudainement à basculer entre deux valeurs différentes. (Juste quelque chose à considérer ...)v
est normalement utilisé pour exécuter alternativement deux états à partir d'une liste de trois états ou plus, alors une corruption dev
pourrait amener le programme à exécuter alternativement deux états complètement différents - cela pourrait entraîner des résultats inattendus et indésirables. La leçon à tirer de ceci est: toujours effectuer des vérifications de plausibilité sur vos données.Si ce doit être l'entier 1 ou 0, alors la façon dont vous le faites est très bien, même si les parenthèses ne sont pas nécessaires. Si ces a doivent être utilisés comme booléens, vous pouvez simplement faire:
la source
Est assez !
la source
v = (v==0 ? 1 : 0);
" . Tout le monde trouve différentes façons de jouer au golf; et ne répond pas réellement à la question. C'est pourquoi j'ai voté pour cette réponse.Liste des solutions
Il y a trois solutions que je voudrais proposer. Tous les convertir toute valeur
0
(si1
,true
etc.) ou1
(si0
,false
,null
etc.):v = 1*!v
v = +!v
v = ~~!v
et un supplémentaire, déjà mentionné, mais intelligent et rapide (bien que ne fonctionne que pour
0
s et1
s):v = 1-v
Solution 1
Vous pouvez utiliser la solution suivante:
Cela convertira d'abord l'entier en booléen opposé (
0
àTrue
et toute autre valeur àFalse
), puis le traitera comme entier lors de la multiplication par1
. En conséquence,0
sera converti en1
et toute autre valeur en0
.Pour preuve, voyez ce jsfiddle et fournissez toutes les valeurs que vous souhaitez tester: jsfiddle.net/rH3g5/
Les résultats sont les suivants:
-123
convertira en entier0
,-10
convertira en entier0
,-1
convertira en entier0
,0
convertira en entier1
,1
convertira en entier0
,2
convertira en entier0
,60
convertira en entier0
,Solution 2
Comme l'a noté mblase75, jAndy avait une autre solution qui fonctionne comme la mienne:
Il fait aussi d'abord booléen à partir de la valeur d'origine, mais utilise
+
au lieu de1*
le convertir en entier. Le résultat est exactement le même, mais la notation est plus courte.Solution 3
Une autre approche consiste à utiliser l'
~~
opérateur:Il est assez rare et se convertit toujours en entier de booléen.
la source
+
pour la convertir en un nombre, c'est donc+!v
équivalent à votre solution (solution de jAndy dans les commentaires de l'OP).1*
peut être remplacé par+
lorsque vous essayez de convertir un booléen en entier. Tout le reste dans ma réponse reste le même. La réponse de jAndy est correcte, mais la mienne est plus détaillée. J'ajouterai sa solution à ma réponse.Pour résumer une autre réponse, un commentaire et ma propre opinion, je suggère de combiner deux choses:
Voici la fonction que vous pourriez placer dans une bibliothèque ou peut-être envelopper dans un plugin pour un autre Framework Javascript.
Et l'utilisation est tout simplement:
Les avantages sont:
la source
function toggle(i){ return i == 0 ? 1 : 0 }
?Je ne sais pas pourquoi tu veux construire tes propres booléens? J'aime les syntaxes funky, mais pourquoi ne pas écrire du code compréhensible?
Ce n'est pas le plus court / le plus rapide, mais le plus clair (et lisible pour tout le monde) utilise l'état if / else bien connu:
Si vous voulez être vraiment clair, vous devez utiliser des booléens au lieu de chiffres pour cela. Ils sont assez rapides pour la plupart des cas. Avec les booléens, vous pouvez simplement utiliser cette syntaxe, qui gagnera en brièveté:
la source
=== 0
. Avec un échantillon d'entrée de7
, la sortie correcte est0
, mais cela sortira1
.Une autre forme de votre solution originale:
EDIT: Merci TehShrike et Guffa pour avoir signalé l'erreur dans ma solution d'origine.
la source
'opacity:'+true
et vous vous retrouvez avecopacity:true
au lieu deopacity:1
.Je voudrais le rendre plus explicite.
Que veut
v
dire?Par exemple, lorsque v est un état. Créez un statut d'objet. En DDD, un objet de valeur.
Implémentez la logique dans cet objet de valeur. Ensuite, vous pouvez écrire votre code d'une manière plus fonctionnelle et plus lisible. Le changement d'état peut être effectué en créant un nouvel état basé sur l'état actuel. Votre instruction / logique if est ensuite encapsulée dans votre objet, que vous pouvez annuler. Un valueObject est toujours immuable, il n'a donc pas d'identité. Donc, pour changer sa valeur, vous devez en créer une nouvelle.
Exemple:
la source
Une autre façon de procéder:
la source
Cela manque:
Cela fonctionne aussi comme round robin:
Ou
Le charme de la dernière solution, il fonctionne également avec toutes les autres valeurs.
Pour un cas très spécial, comme obtenir une valeur (changeante) et
undefined
, ce modèle peut être utile:la source
Comme il s'agit de JavaScript, nous pouvons utiliser l'unaire
+
pour convertir en int:Cela va logiquement
NOT
la valeur dev
(donnanttrue
siv == 0
oufalse
siv == 1
). Ensuite, nous convertissons la valeur booléenne retournée en sa représentation entière correspondante.la source
Juste pour les coups de pied:
v = Math.pow(v-1,v)
bascule également entre 1 et 0.la source
Un de plus:
v=++v%2
(en C ce serait simple
++v%=2
)ps. Oui, je sais que c'est une double affectation, mais ce n'est qu'une réécriture brute de la méthode de C (qui ne fonctionne pas en l'état, car l'opérateur de pré-incrémentation JS ne renvoie pas lvalue.
la source
++
opérateur (ce n'est pas une valeur l). Quant àv=++v%2
, vous modifiezv
deux fois. Je ne sais pas si c'est bien défini en JavaScript, mais ce n'est pas nécessaire.v = (v+1) % 2
.c++
c'est parce que l'opérateur de pré-incrémentation a une priorité plus élevée et modifie la variable «en place», de sorte qu'elle peut être utilisée comme valeur l. Je pense que l'implémentation de JS++
est telle qu'elle ne peut pas être traitée comme une valeur l: / Et oui, c'est redondant, mais j'essayais de montrer juste une autre méthode - il y a déjà de meilleures solutions publiées :)Si vous êtes assuré que votre entrée est soit 1 soit 0, alors vous pouvez utiliser:
la source
définir un tableau {1,0}, définir v sur v [v], donc v avec une valeur de 0 devient 1, et vice versa.
la source
Une autre façon créative de le faire, en
v
étant égale à n'importe quelle valeur, reviendra toujours0
ou1
la source
!!
résultent en rien en maths logiques, vous pouvez!!!!
y entrer et seront les mêmes mais il en résultera 4 opérations inutiles!!
jettera à un bool.!!(1) === true
et!!(0) === false
v = Boolean(v^1)
serait plus informatif, merci pour l'explication - je n'ai pas pensé au casting!
la transforme en booléen. Ajouter un autre!
annulera ce booléen. Le casting est implicite ici, et le résultat final fonctionne. Il n'y a pas besoin de -1.Si les valeurs possibles pour v ne sont que 0 et 1, alors pour tout entier x, l'expression: v = Math.pow ((Math.pow (x, v) - x), v); fera basculer la valeur.
Je sais que c'est une solution laide et l'OP ne le cherchait pas ... mais je pensais à une autre solution quand j'étais dans les toilettes: P
la source
Non testé, mais si vous recherchez un booléen, je pense que
var v = !v
cela fonctionnera.Référence: http://www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables
la source
fonctionnera pour v = 0 et v = 1; et basculer l'état;
la source
S'il n'y a que deux valeurs, comme dans ce cas (0, 1), je pense qu'il est inutile d'utiliser int. Optez plutôt pour le booléen et travaillez en morceaux. Je sais que je suppose, mais en cas de basculement entre deux états, le booléen semble être le choix idéal.
la source
Eh bien, comme nous le savons, en javascript, seule cette comparaison booléenne vous donnera également le résultat attendu.
c'est à dire
v = v == 0
suffit pour cela.Voici le code pour cela:
JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/
En espérant que cela vous aidera :)
la source
true
etfalse
. Vous pouvez utiliserv == 0
pour déterminer la valeur de la variable dans une condition, mais si vous souhaitez utiliser la valeur 0 ou 1, vous devez utiliser quelque chose commev == 0 ? 0 : 1
ouNumber(v)
pour l'obtenir. (En outre, vous pouvez utiliserv = !v;
pour basculer entretrue
etfalse
.)Il tapera la valeur booléenne inversée en nombre, qui est la sortie souhaitée.
la source