476

I want to toggle a variable between 0 and 1. If it's 0 I want to set it to 1, else if it's 1 I want to set it to 0.

This is such a fundamental operation that I write so often I'd like to investigate the shortest, clearest possible way of doing it. Here's my best so far:

v = (v == 0 ? 1 : 0);

Can you improve on this?

Edit: the question is asking how to write the above statement in the fewest characters while retaining clarity - how is this 'not a real question'? This wasn't intended to be a code-golf exercise, though some interesting answers have come out of people approaching it as golf - it's nice to see golf being used in a constructive and thought-provoking manner.

Cœur
  • 32,421
  • 21
  • 173
  • 232
Ollie Glass
  • 17,505
  • 18
  • 65
  • 98
  • 20
    This looks already simple/clear/short to me. – Mob Aug 02 '11 at 11:25
  • 137
    trickery: `v = +!v;` – jAndy Aug 02 '11 at 11:28
  • 48
    If 'better' also means 'faster': http://jsperf.com/v-0-1-0. – pimvdb Aug 02 '11 at 11:38
  • 3
    @pimvdb: Interresting, but I think that you should test with the assignment also, as `v ^= 1;` doesn't behave the same as `v = v ^ 1;`: http://jsperf.com/v-1-v – Guffa Aug 02 '11 at 12:11
  • 7
    @Mobinga: +1. This is as simple as it should get. All the other answers i see are confusing, and some of them change the logic; introducing bugs. – Ian Boyd Aug 02 '11 at 12:21
  • @Guffa: how so? I don't see `v = v ^ 1` on the page you linked to. – LarsH Aug 02 '11 at 14:39
  • @LarsH: Noone has suggested to use `v = v ^ 1;`, but pimvdb:s test evaluated the expression `v ^ 1`, which would be equivalent to testing `v = v ^ 1;` instead of `v ^= 1;`. The result is the same, but they don't perform exactly the same. – Guffa Aug 02 '11 at 16:42
  • 3
    Why not use `if(v == 0) { v = 1; } else { v = 0; }`? I doubt there is any difference in speed and it is a lot easier to read if you're new to the code. If it's easier to read and understand and there's no real performance difference, then it's better. – Kristof Claes Aug 02 '11 at 17:09
  • 5
    I must admit this question is eerily interesting even though it seems so simple... – Dominic K Aug 02 '11 at 17:11
  • 1
    Your way is the clearest, so there is no reason to change it. It is also robust, because the resulting value for `v` is guaranteed to be in the desired range, regardless of the value it had before. And this robustness is even perfectly obvious. – starblue Aug 02 '11 at 18:36
  • @Guffa: I guess I misunderstood you. When you said they don't "behave" the same, I thought you meant the result was different, but I guess you're talking about differences of speed alone. – LarsH Aug 02 '11 at 18:36
  • I am also a performance freak however for me personally no performance gain (especially when its this small) is worth sacrificing code readability. That's why I have to vote for this solution. – brezanac Aug 02 '11 at 19:14
  • @holodoc: Vote for which solution? – Guffa Aug 02 '11 at 20:28
  • @Guffa I voted for the OP's solution (`v = (v == 0 ? 1 : 0);`) because it shows clearly the logic behind that line of code. I am not saying that other solutions are bad however from my personal experience sticking to the logic behind code is always the preferred way especially when working with other people or if there is a possibility that the code might be changed a lot in the future by others. – brezanac Aug 02 '11 at 20:37
  • @holodoc: No, you voted for the question. Votes for questions are not compares to votes for answers, it's compared to votes for other questions. – Guffa Aug 02 '11 at 20:41
  • @Guffa I don't understand whats the big deal? I voted for the OPs solution inside his / hers question because he / she asked if there is a better way from the one he / she is using / has provided. – brezanac Aug 02 '11 at 20:50
  • @holodoc: It's not a big deal, but that is simply not how the site works. You can of course vote for the question, but that won't work as a vote for an answer. – Guffa Aug 02 '11 at 20:52
  • @Guffa I did not vote for the OP's post in order to qualify it as an accepted answer I just wanted to show him that his original solution was the best in my opinion. – brezanac Aug 02 '11 at 20:56
  • 2
    @holodoc: You can use any reason you like, but the vote will just count as a vote for a good question. – Guffa Aug 02 '11 at 21:15
  • @Guffa What exactly should I do to make it absolutely clear that I don't care what for my vote is used aside from the fact that it lets the OP know that his / hers way is the best in my opinion? Would you stop making remarks if I upvote your post? – brezanac Aug 02 '11 at 21:29
  • @holdoc: I'm trying to make you understand that your vote won't be interpreted that way, but you can continue to think that if you like. – Guffa Aug 02 '11 at 21:41
  • do i detect a hint of perfectionism? ;) – wim Aug 03 '11 at 01:40
  • 8
    @holodoc A better solution to expressing your opinion would be to create an answer that says you feel the original is the best way, and elaborate on WHY you feel that is the case. that also allows other people to easily side with your answer by voting it up. – Chuck van der Linden Aug 03 '11 at 08:43
  • @Chuck van der Linded I don't like redundancy. Everything what I had to say was said in my comments on the original post. – brezanac Aug 03 '11 at 14:10
  • Whatever you use, make it a macro so you don't repeat all over the place - oh, if you were using C I mean. Make it a function :) – Aram Kocharyan Feb 23 '12 at 07:28
  • This question appears to be off-topic because it a code golf question – Michael Berkowski Dec 16 '14 at 16:48
  • 2
    Your question made one of the greatests Rube Goldberg machines in the entire stackoverflow. – Victor Ivens Apr 08 '15 at 13:43
  • You might not wanna get fancy. Cause you want to keep it readable. – Arnaldo Capo Sep 23 '18 at 13:07

31 Answers31

742

You can simply use:

v = 1 - v;

This of course assumes that the variable is initialised properly, i.e. that it only has the value 0 or 1.

Another method that is shorter but uses a less common operator:

v ^= 1;

Edit:

To be clear; I never approached this question as code golf, just to find a short way of doing the task without using any obscuring tricks like side effects of operators.

Guffa
  • 640,220
  • 96
  • 678
  • 956
  • 211
    These are beautiful lines of code, like finely cut glass or rare flowering orchids. I love how you've reached straight through the logical layer and dealt directly with the math of 1 and 0 with the most optimal operations possible. I'll be using these in my own projects, but unfortunately when I need the code to be understood by coworkers I'll have to default to a more logic-based approach. Thank you though, your answer has made my day. – Ollie Glass Aug 02 '11 at 11:53
  • 37
    You can always add a comment saying what the code does. – Prusse Aug 02 '11 at 12:11
  • 2
    In addition to obscuring the intentions of the logic, you've introduced a bug by changing the logic. – Ian Boyd Aug 02 '11 at 12:18
  • 5
    @Ian Boyd: What do you mean by "the logic" then? Do you mean the code in the question, or the specification (the first sentence)? I went for the specification rather than the code, and I clearly stated the limitations of the method in my answer. – Guffa Aug 02 '11 at 12:30
  • @Guffa, the specification. "If it's 0, I want to set it to 1, else set it to 0." Sample input `v=7`. Result from original algorithm: `0`. Result from modified algorithm: `6`. Imagine the input comes from a user-editable configuration file; where the user can enter zero/non-zero. – Ian Boyd Aug 02 '11 at 13:49
  • 7
    @Ian Boyd: That's not between 0 and 1. Also again, I clearly specified the limitations of the method in the answer. – Guffa Aug 02 '11 at 13:56
  • 9
    @KevinDTimm: Perhaps it does not answer your interpretation of the question, but it seems to answer the interpretation of the person asking it... – Guffa Aug 02 '11 at 14:06
  • 25
    @Kevin: it's not true that this clearly does not answer the question as asked. The q said "I want to toggle a variable between 0 and 1." A very reasonable interpretation is that this implies that the value of the variable is already either 0 or 1. This interpretation / limitation was made explicit in the answer. What in the world can you object to? – LarsH Aug 02 '11 at 14:18
  • This is a great trick Guffa. I used this during the jurassic period when programming in ASP (many years prior to ASP.NET) in order to perform odd-even coloring of rows in a table. – Husein Roncevic Aug 02 '11 at 14:19
  • 1
    So, how does it fulfill this line from the OP when the value of v is not 1? `If it's 0, I want to set it to 1, else set it to 0.` – KevinDTimm Aug 02 '11 at 14:53
  • 1
    I personally find this elegant but not self documenting -- because I can't look at it and easily understand what its doing. – JD Isaacks Aug 02 '11 at 15:21
  • 23
    +1 for `v ^= 1`. If that's not clear then I think you should stop programming and practice the fundamentals of logical operations for a bit. `v = 1 - v` is clever but not as clear, though, since it's not a logical operation. It's much better to represent logic with logic rather than math. – Matthew Read Aug 02 '11 at 15:29
  • 50
    @Matthew to say that someone who does not find `v ^= 1` clear should stop programming is a little harsh I think. As previously stated its not one of the more common operators and it does not do the same thing as `v = v ^ 1`. Also the operator means something completely different in different languages (VB). Yes a quick look-up will tell you that its an XOR operator and you will understand what its doing, but to many it may not be obvious at first glance. I don't think that means you need to quit your job. – JD Isaacks Aug 02 '11 at 15:48
  • 80
    If you save 15 characters by writing this but then use 40 characters of comments to explain it, is it really an improvement? – Michael Myers Aug 02 '11 at 15:49
  • 6
    @JohnIsaacks `v ^= 1` and `v = v^1` are exactly the same, just like `v += 1` and `v = v+1` are the same. At least, the results are the same for a single thread; there may be languages/implementations where the intermediate value is handled differently. – Matthew Read Aug 02 '11 at 15:56
  • 2
    @Michael Myers, I think it still is an improvement. Readers can see what's happening and it may just make their day to see something neat like this. Quentin's answer below is probably better for clarity but this is still pretty slick. – Steven Hepting Aug 02 '11 at 16:19
  • 1
    @Corey - how about when v > 1? The OP says toggle but does not define that v can only be 0 or 1 (he says, `If it's 0, I want to set it to 1, else set it to 0` which does not explicitly say that v must be 0 or 1 - start value could be any number) – KevinDTimm Aug 02 '11 at 18:54
  • 1
    -1 This is code obfuscation, and such is reprehensible. You'd need a long comment to explain what is going on. – Lotus Notes Aug 02 '11 at 19:36
  • 4
    @Lotus Notes: You don't see what it does? Well, not everyone sees what the code in the question does either. – Guffa Aug 02 '11 at 20:29
  • 1
    It doesn't matter whether or not I understand it. The most important aspect of code is readability, and what matters is that the random mediocre Joe Coder on your team can immediately understand it. Who cares if you "saved" 15 characters? – Lotus Notes Aug 02 '11 at 21:22
  • 9
    @Lotus Notes: No, not every programmer has to immediately understand all code. You have to be able to expect a certain level of knowledge, otherwise all your code will end up looking like "Javascript for Dummies"... – Guffa Aug 02 '11 at 21:57
  • A trick where v can be any value and still preserve the original meaning: `v = 1 - !!v`. This is worse than `v = +!v` though. – Sean Aug 02 '11 at 22:37
  • 3
    @Michael Myers Yes, it's an improvement, 15 characters less of code means 15 characters less of chance for making a mistake. Comments aren't executable (usually ;) ) – Chris Hasiński Aug 03 '11 at 02:41
  • "this of course assumes..." how many bugs has THAT phrase lead to? I'd rather have something that was instantly obvious at first glance instead of making me puzzle out the math or logic in order to be sure I understand it, and that could throw an exception if 'assumptions' are violated. Lots of points for 'style' and 'elegant code' but not for readable or reliable code. – Chuck van der Linden Aug 03 '11 at 08:37
  • 3
    @Chuck van der Linden: You always assume that some conditions are met for code to work, it's impossible to write code that does something sane regardless of the conditions. It's for example easy to create an object for `v` so that not even `v == 0` works... – Guffa Aug 03 '11 at 09:15
  • 1
    Downvote. Reasoning: This is such horrible advice that I think the internet cringed at it's posting. Obviously it's "shorter" but it's far from better. Very very far. – Noon Silk Aug 03 '11 at 11:21
  • 15
    Anyone who does not understand what this code does *is not a programmer*. If non-programmers are confused by reading this code, your problem is that non-programmers are reading your code. – Tom Anderson Aug 03 '11 at 12:58
  • can you understand what the code does as you read it, as easily as say reading a word like 'toggle' or do you understand it after you read it and figure out what it does in a sort of *wait, one minus v? what does that do? ponder potential inputs and outputs, oh I see* sort of process. (and perhaps even then ONLY if you understand the limited range of values intended for v, and where and how prey-tell is that particular intent expressed in the code? and what if you read this without having read that part?) – Chuck van der Linden Aug 03 '11 at 15:29
  • 1
    @KevinDTimm In that case, it's not being toggled between 0 and 1 as the question specifies. I see how it can be read both ways, though. – Corey Aug 03 '11 at 16:46
  • 2
    @Noon Silk: you've said it's horrible but have not said why. "It's horrible" is not usually considered "reasoning" for a downvote. – LarsH Aug 03 '11 at 21:44
  • 2
    @Chuck van: "this of course assumes..." makes assumptions explicit, which is far better than unstated assumptions. Given the explicit assumption, you can make a well-informed decision about whether the code meets your needs or not. – LarsH Aug 03 '11 at 21:46
  • @LarsH: It's reasoning enough (i.e. not downvoting due to incorrectness, but due to serious disagreement with the style). – Noon Silk Aug 04 '11 at 02:10
  • @Noon: "style" is a little better than just "horrible". – LarsH Aug 04 '11 at 12:28
  • 6
    What kind of programmers don't understand logical operators? – Rob Fox Aug 05 '11 at 11:15
  • Both of the solutions given are good, and in most cases I would probably use `v ^= 1;` in my own code. There is one safety issue to consider: If `v` is static, not a boolean, and the program runs in a noisy environment, it is conceivable (probable) that the location of `v` in RAM could be corrupted so that `v` becomes something other than `0` or `1`. In these conditions the OP's code or @Quentin 's answer `v = (v ? 0 : 1);` would be more robust. – oosterwal Aug 08 '11 at 17:07
  • 1
    In this case, v ^= 0 works identically, yes? Does it make any negligible difference if you use 0 instead of 1 here, in terms of speed? – Ada Aug 16 '11 at 21:15
  • 2
    @Nathanael: Using `v ^= 0;` doesn't change the value of the variable. The `^=` operator does a bitwise xor, and `x xor 0 == x`. Using `v ^= 1;` does an xor with the value 1, thus flipping the first bit in v between 0 and 1. – Guffa Aug 16 '11 at 21:21
  • -1: The OP's way is significantly clearer. – Thomas Eding Nov 18 '11 at 21:23
  • 1
    +1. I personally think `v = 1 - v` is far clearer than `v = (v == 0 ? 1 : 0)`. The latter is basically an almost-obfuscated way of writing `if (v == 0) { v = 1; } else { v = 0; }`. – Claudiu Jun 27 '12 at 15:20
  • Both are bound to be lightning fast, (I haven't tested the speed, but I see little chance for much code to be faster than a single subtraction or a single bitwise operation), and with comment like //toggle 1/0 it's still short enough for load time to be insignificant in difference, and then plenty clear. – Jimbo Jonny Nov 14 '12 at 20:20
  • may I ask, what does ^= do? – Lucas Apr 11 '13 at 11:37
  • 2
    @think123: `v ^= 1;` does the same as `v = v ^ 1`. It's the exclusive or operator. See: http://msdn.microsoft.com/en-us/library/0zbsw2z6%28v=VS.80%29.aspx – Guffa Apr 11 '13 at 13:04
  • Why the downvote? If you don't explain what it is that you think is wrong, it can't improve the answer. – Guffa Mar 03 '14 at 15:55
  • i dont get it. the op asked to toggle between 1 and 0. assuming `v = 0`, `v = 1 -v` = `-1` why is this the selected answer? – Rafael Herscovici Jul 21 '14 at 17:52
  • 1
    @Dementic: `1 - 0` is not `-1`, it is `1`. – Guffa Jul 21 '14 at 18:08
  • Added an answer below... any expert opinion on that.. appreciated... – Vikash Pandey Oct 04 '16 at 09:20
  • In addition to all the other clever solutions, your `v ^= 1;` could be more robust against bad input as `v ^= 1 & v;`. If I'm awake, the `1 & v` will make sure the input is `1` or `0` while the `v ^= ` will do the toggle as you designed. So, the robust solution is `v^=1&v`, though I like @Quentin's `v=+!v` for arcane brevity. – Umbrella Jun 26 '17 at 15:28
  • @JD Issacs - You're the one whose harsh by exaggerating what he said. " . . . you should stop programming and practice the fundamentals of logical operations for a bit . . . " does not imply "quitting your job" but rather - taking a pause to sharpen your lacking skillset. – Adrian Bartholomew Jan 10 '19 at 18:13
  • wow that's beautiful, so elegant – Pixelomo Aug 01 '19 at 07:05
347

Since 0 is a false value and 1 is a true value.

v = (v ? 0 : 1);

If you are happy to use true and false instead of numbers

v = !v;

or if they must be numbers:

v = +!v; /* Boolean invert v then cast back to a Number */
Joe
  • 73,764
  • 18
  • 123
  • 142
Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • 57
    just put the magic `+` before that `!`. Ohhh that looks soooo dirty! but cool :p – jAndy Aug 02 '11 at 11:29
  • 1
    @Quentin - this will break the guy's code if he has `switch(v){ case 0 ...` or if(v == 0) or if v === 0. You're changing his result in addition to his approach.... – Brian Aug 02 '11 at 11:31
  • 34
    Make a smiley of it: `({v :+! v}).v`. – pimvdb Aug 02 '11 at 11:32
  • 17
    @Brian: not with that magic `+` sign! ¯\\_(ツ)_/¯ – jAndy Aug 02 '11 at 11:33
  • @jAndy what's the magic plus? – Ollie Glass Aug 02 '11 at 11:34
  • 1
    @OllieG: I'll just make a number out of the boolean value. 0/1 – jAndy Aug 02 '11 at 11:36
  • @Brian — As I said "If you are happy to use". I made it clear there were provisos. – Quentin Aug 02 '11 at 11:51
  • @jAndy — That's nifty, I didn't realise it worked on non-strings. – Quentin Aug 02 '11 at 11:51
  • I was going to say the same thing as point A.. Had no idea about point C though. – JD Isaacks Aug 02 '11 at 15:18
  • 11
    +1 for `v = (v ? 0 : 1)` as clear and idiomatic JS. – Bennett McElwee Aug 03 '11 at 00:45
  • Sorry but could someone please be kind enough to explain that last line 2 me? v = +!v; I dont understand.. + NOT v? What language is this in? I tried this in C# on an int and I got a compiler error. – Maxim Gershkovich Aug 03 '11 at 09:13
  • 1
    @Maxim — It is JavaScript (see the tags on the question). The comment in my answer explains how it works. The [unary plus operator](https://developer.mozilla.org/en/JavaScript/Reference/Operators/Arithmetic_Operators) converts to numbers. – Quentin Aug 03 '11 at 09:27
  • 1
    +1 for providing solutions that are both simple and robust. Even if non-boolean `v` becomes corrupted and is no longer a value of either `0` or `1`, it will be reassigned a valid value. – oosterwal Aug 08 '11 at 17:12
  • What does the '+' in v = +!v; do? – anotherDev Dec 08 '16 at 06:02
  • 1
    @HarshaKanchina — What the JS comment next to it in the code says it does, and what the Stackoverflow comment just 3 comments before your comment says it does. – Quentin Dec 08 '16 at 07:15
  • Yeah. Got it. Missed the comment mentioning it. I just saw the code and did not get the meaning clearly from the comment as I'd never seen the + operator used for converting something to numbers! Thanks though. – anotherDev Dec 08 '16 at 12:17
200

v = (v + 1) % 2 and if you need to cycle through more values just change 2 for (n + 1). Say you need to cycle 0,1,2 just do v = (v + 1) % 3.

Prusse
  • 4,217
  • 2
  • 20
  • 28
75

You could write a function for it and use it like:

v = inv(v)

Daniel
  • 1,519
  • 11
  • 13
  • 30
    +1 I strongly agree this is the cleanest solution (...but then what goes in the `inv` function :P) – Lea Hayes Aug 02 '11 at 16:13
  • 4
    I wish I could give this answer more than just +1. If common code is not blindingly obvious, it should be wrapped in a function with a descriptive name. – TehShrike Aug 02 '11 at 20:45
  • 11
    @TehShrike do you consider `inv` to be a descriptive name? – Bennett McElwee Aug 03 '11 at 00:46
  • 3
    @Bennett McElwee: inv = invert. Always seemed like a common abbreviation to me. – Daniel Aug 03 '11 at 07:15
  • 51
    Why abbreviate it then, call it 'invert' or 'toggle' and have the code be readable. it's not as if we are trying to fit this stuff onto an 80 column punchcard or something. – Chuck van der Linden Aug 03 '11 at 08:24
  • I also agree on considering writing helper functions for things you need more often. – Nasaralla Aug 03 '11 at 13:36
  • 2
    @Chuck van der Linden: I just made the suggestion to use `inv` but you can use `invert` or `toggle` of course if you like. But because the author stated that he writes it very often I thought it would be better to keep it short. And by the way: this behaviour is seen quite often. See for example python's `len` for determining the length of a list. – Daniel Aug 03 '11 at 21:03
  • Downvoted because this doesn't actually answer the question - it should have included what actually goes into inv(). And I have to agree with the above that the name 'inv' is a pretty bad name; 'toggle' would be much better. – fluffy Aug 03 '11 at 21:19
  • @Bennett McElwee no, inv() is not very descriptive in my mind. This is the only solution that suggested wrapping up the functionality in another function, though. Name it InvertZeroAndOne() or something, and there you go! :-D – TehShrike Aug 03 '11 at 22:26
  • 1
    You could even implement as `function invert(d) { try { d /= d } catch(err) { return 1; } return 0; }` :) – Brian Aug 06 '11 at 14:46
  • 1
    inv = invert? invoke? invite? involve? invisible? rule of them - abbreviations are always obvious to the writer. Sometimes even to the reader to ;) – Michael Durrant Sep 06 '11 at 17:26
  • I'm sorry, but this is dumb. Use the `!` operator. – Thomas Eding Nov 18 '11 at 21:24
  • 1
    @trinithis: The ! operator will cast 0 or 1 to true or false respectively. That is not what the questioner wanted. – Daniel Nov 19 '11 at 12:04
50

If you don't care about any possibility other than 1:

v = v ? 0 : 1;

In the above case, v will end up being 1 if v is 0, false, undefined or null. Take care using this kind of approach - v will be 0 even if v is "hello world".

Brian
  • 2,688
  • 13
  • 12
  • 2
    That won't flip the value. You mean `v = v ? 0 : 1`. – Guffa Aug 02 '11 at 11:48
  • 3
    @Guffa - +1 for catching my dyslexia... – Brian Aug 02 '11 at 11:54
  • 3
    This is my favourite logic-based answer which I can use with coworkers (I'm seeing @Guffa's answer as number-based). I like how you've taken the unnecessary test (v==0) and brackets out, stripping it down to the absolute minimum character count. Thank you. – Ollie Glass Aug 02 '11 at 12:06
  • 1
    I'm a big fan of @Guffa's answer too - in the words of lynard skynard, keep it simple man ;) – Brian Aug 02 '11 at 12:11
  • 2
    +1 for understanding "truthy" values. – zzzzBov Aug 03 '11 at 17:18
  • i find this more readable than the ultra-skinny versions. I really like having a 'test' in their as indicated by the '?'. The versions thaat are doig the cleverer ways like 1-x are cool but more cryptic and as code readability (by all) and maintainability (by all) are key I like this solution. – Michael Durrant Sep 06 '11 at 17:29
46

Lines like v = 1 - v, or v ^= 1 or v= +!v will all get the job done, but they constitute what I would refer to as hacks. These are not beautiful lines of code, but cheap tricks to have the intended effect. 1 - v does not communicate "toggle the value between 0 and 1". This makes your code less expressive and introduces a place (albeit a small one) where another developer will have to parse your code.

Having instead a function like v = toggle(v) communicates the intent at the quickest glance.

Ray
  • 4,589
  • 3
  • 26
  • 54
  • 8
    -1, seriously, `v=1-v` doesn't communicate the toggle? – Blindy Aug 02 '11 at 14:31
  • 23
    `1-v` can communicate indeed toggle, but that's that the only thing it communicates. For example, it can also communicate a line with zero at `v=1`, or a mirroring transformation centered at `v=0.5`. In this sense it is relatively ambiguous. It is true that knowing that `v` can only ever be `0` or `1` limits its intended meaning, but that forces other developers (or your future self) to understanding that context before being able to understand this simple line. You can't be much clearer than `v = toggle(v)` – Ray Aug 02 '11 at 14:42
  • I said `v=1-v`. That is not a line sir, that is a toggle. Go ahead and feed a few points through it to see why. And keep in mind that while you're having trouble with it for whatever reason, for most of us it's become a pattern in itself. – Blindy Aug 02 '11 at 14:45
  • Don't get me wrong; I use it all the time in throwaway utility stuff. I totally understand the idiom. That said, these kind of tricks don't fly in an enterprise environment. – Ray Aug 02 '11 at 14:49
  • Then again an "enterprise environment" has to have a 300mb code base or it won't fly. What better way to make people think you're working than writing inconsequential functions? http://thedailywtf.com/articles/A_False_Detector.aspx My -1 stands :) – Blindy Aug 02 '11 at 14:52
  • +1 not because I think the function is a good idea, but because I agree that `v=1-v` is unclear. It's perfectly clear if you know the value of v is only ever one of two values, but otherwise it looks unrelated to toggling. Op is looking for a method that is mostly unambigious, if I am assessing the question and comments on other answers correctly. – Matthew Read Aug 02 '11 at 15:26
  • 10
    `v ^= 1` is perfectly clear if you understand logical operations, though, which you had better if you're a programmer. I think that's the difference between that and `v=1-v`; one's a logical operation and one's an arithmetic operation, and we're trying to represent a logical concept not a mathematical one. – Matthew Read Aug 02 '11 at 15:30
  • 1
    @Matthew Read; `v ^= 1` is perfectly clear to folks like you and me. I don't, however, always trust the support developers who will be maintaining software down the road. It's often for their benefit that I go to pains to make code as unambiguous as possible (and have my team do the same). I've seen some shocking ignorance played out in my time. – Ray Aug 02 '11 at 16:12
  • 6
    @Matthew Read: This is a great statement, which sums up my thoughts well: "we're trying to represent a logical concept not a mathematical one." Even `v ^= 1` has some ambiguity, though, as it can be interpreted as a bitwise-xor. – Ray Aug 02 '11 at 16:14
  • @Ray Fair point. JavaScript only has bitwise XOR. – Matthew Read Aug 02 '11 at 16:21
  • 6
    for programmers (and yes, i do mean geeks like us), these are quite clear. They aren't hacks, because they are elegant solutions due to their simplicity. – gion_13 Aug 02 '11 at 17:02
  • It's not truly enterprise-ready until you've defined 5 different toggle functions with different names that do the same thing. – Nate C-K Aug 02 '11 at 21:20
  • @Nate C-K--the point is having clean code. If you've got that situation, it isn't clean either. If my developers were pulling that, there would be a lot of explaining, followed by refactoring. – Ray Aug 02 '11 at 22:05
  • 3
    The other problem with v = 1 - v is that you are making a LOT of assumptions as to the state of v, and this breaks the moment someone does something with v you didn't expect, but you will never know it's broken. A toggle function can also throw an exception if v is anything except 1 or 0, so it can also 'guard' the intent of this variable instead of presuming that all people who touch this code will understand exactly what it is and treat it properly. Thus there is a lot less that can go wrong with it. – Chuck van der Linden Aug 03 '11 at 08:28
  • 3
    +1 for this one. The question talks about **clarity**. And there's absolutely no clarity to me when I read "v=1-v" even though it seems so clever, smart and optimized. What is written in Arial 80 on my personal board: "Readability before optimization". – Olivier Pons Aug 05 '11 at 08:05
  • "v=1-v" is absolutely clear, obvious, and should be part of any serious programmer's toolkit. Anyone who doesn't understand it, or who finds it unclear, really needs to try harder. – Graham Borland Aug 18 '11 at 15:29
  • 2
    If I see `v = 1 - v` I know what it does. If I see `v = toggle(v)` I know what it *might* do, if the programmer and I share the same idea of the meaning of the word "toggle", and if the definition of `toggle` isn't full of bugs. – hobbs Jan 28 '12 at 04:25
  • hacks? The whole concept of programming is a big hack to get the job done... – Thanasis Ioannidis Sep 13 '12 at 23:22
  • If you think that looks like a hack, simply add a comment "Toggles between 1 and 0". Not that hard I guess... – Tara Feb 07 '13 at 14:15
  • 1
    @Ray Considering the OP asked for the "shortest, clearest way" to get the command to be executed... just using "toggle(v)" does not provide a clear picture... It makes the concept behind what the function is supposed to do... but unless you back it up with an actual function then it's just a function name... v=1-v is clear, and given that the only possible expected inputs are 1 or 0, then the intention is quite clear... If the input is 1, the output is 0; and vice versa... And while `v^=1` is much quicker, to a novice programmer, it doesn't clarify what is happening... – Eliseo D'Annunzio Aug 15 '14 at 02:24
  • Yes, of course, the assumption would be that we would create the toggle function! My intention was to focus less on the implementation details of such function and direct our attention instead to the benefits of encapsulating the logic in a function. – Ray Aug 15 '14 at 12:00
  • But the OP wasn't asking for it to be encapsulated into a function... Quoted from the OP: "the question is asking how to write the above statement in the fewest characters while retaining clarity" – Eliseo D'Annunzio Aug 25 '14 at 23:33
  • @Ray, you stated that "1-v can communicate indeed toggle, but that's that the only thing it communicates.". You went on to talk about enterprise environments and a bunch of other topics. The requirement is to toggle V between 0 and 1. Period. Codebase doesn't matter. If the statement says anything else, it's obfuscatory and wasteful. The requirement is a boolean or single bit toggle. `v ^= 1`, where v is a single bit value is the answer. – Xalorous Oct 28 '15 at 00:09
38

(Honesty and mathematical integrity - given the number of votes on this "answer" - have led me to edit this answer. I held off as long as possible because it was intended as a short quip and not as anything "deep" so putting in any explanation seemed counter to the purpose. However, the comments are making it clear that I should be clear to avoid misunderstanding.)

My original answer:

The wording of this part of the specification:

If it's 0, I want to set it to 1, else set it to 0.

implies that the most accurate solution is:

v = dirac_delta(0,v)

First, the confession: I did get my delta functions confused. The Kronecker delta would have been slightly more appropriate, but not by much as I wanted something that was domain-independent (the Kronecker delta is mainly used just for integers). But I really shouldn't have used delta functions at all, I should have said:

v = characteristic_function({0},v)

Let me clarify. Recall that a function is a triple, (X,Y,f), where X and Y are sets (called the domain and codomain respectively) and f is a rule that assigns an element of Y to each element of X. We often write the triple (X,Y,f) as f: X → Y. Given a subset of X, say A, there is a characteristic function which is a function χA: X → {0,1} (it can also be thought of as a function to a larger codomain such as ℕ or ℝ). This function is defined by the rule:

χA(x) = 1 if x ∈ A and χA(x) = 0 if x ∉ A.

If you like truth tables, it's the truth table for the question "Is the element x of X an element of the subset A?".

So from this definition, it's clear that the characteristic function is what is needed here, with X some big set containing 0 and A = {0}. That's what I should have written.

And so to delta functions. For this, we need to know about integration. Either you already know it, or you don't. If you don't, nothing I can say here will tell you about the intricacies of the theory, but I can give a one sentence summary. A measure on a set X is in essence "that which is needed to make averages work". That is to say that if we have a set X and a measure μ on that set then there is a class of functions X → ℝ, called measurable functions for which the expression X f dμ makes sense and is, in some vague sense, the "average" of f over X.

Given a measure on a set, one can define a "measure" for subsets of that set. This is done by assigning to a subset the integral of its characteristic function (assuming that this is a measurable function). This can be infinite, or undefined (the two are subtly different).

There are lots of measures around, but there are two that are important here. One is the standard measure on the real line, ℝ. For this measure, then ℝ f dμ is pretty much what you get taught in school (is calculus still taught in schools?): sum up little rectangles and take smaller and smaller widths. In this measure, the measure of an interval is its width. The measure of a point is 0.

Another important measure, which works on any set, is called the point measure. It is defined so that the integral of a function is the sum of its values:

X f dμ = ∑x ∈X f(x)

This measure assigns to each singleton set the measure 1. This means that a subset has finite measure if and only if it is itself finite. And very few functions have finite integral. If a function has a finite integral, it must be non-zero only on a countable number of points. So the vast majority of functions that you probably know do not have finite integral under this measure.

And now to delta functions. Let's take a very broad definition. We have a measurable space (X,μ) (so that's a set with a measure on it) and an element a ∈ X. We "define" the delta function (depending on a) to be the "function" δa: X → ℝ with the property that δa(x) = 0 if x ≠ a and X δa dμ = 1.

The most important fact about this to get a-hold of is this: The delta function need not be a function. It is not properly defined: I have not said what δa(a) is.

What you do at this point depends on who you are. The world here divides in to two categories. If you are a mathematician, you say the following:

Okay, so the delta function might not be defined. Let's look at its hypothetical properties and see if we can find a proper home for it where it is defined. We can do that, and we end up with distributions. These are not (necessarily) functions, but are things that behave a little like functions, and often we can work with them as if they were functions; but there are certain things that they don't have (such as "values") so we need to be careful.

If you are not a mathematician, you say the following:

Okay, so the delta function might not be properly defined. Who says so? A bunch of mathematicians? Ignore them! What do they know?

Having now offended my audience, I shall continue.

The dirac delta is usually taken to be the delta function of a point (often 0) in the real line with its standard measure. So those who are complaining in the comments about me not knowing my deltas are doing so because they are using this definition. To them, I apologise: although I can wriggle out of that by using the Mathematician's defence (as popularised by Humpty Dumpty: simply redefine everything so that it is correct), it is bad form to use a standard term to mean something different.

But there is a delta function which does do what I want it to do and it is that which I need here. If I take a point measure on a set X then there is a genuine function δa : X → ℝ which satisfies the criteria for a delta function. This is because we are looking for a function X → ℝ which is zero except at a and such that the sum of all of its values is 1. Such a function is simple: the only missing piece of information is its value at a, and to get the sum to be 1 we just assign it the value 1. This is none other than the characteristic function on {a}. Then:

X δa dμ = ∑x ∈ X δa(x) = δa(a) = 1.

So in this case, for a singleton set, the characteristic function and the delta function agree.

In conclusion, there are three families of "functions" here:

  1. The characteristic functions of singleton sets,
  2. The delta functions,
  3. The Kronecker delta functions.

The second of these is the most general as any of the others is an example of it when using the point measure. But the first and third have the advantage that they are always genuine functions. The third is actually a special case of the first, for a particular family of domains (integers, or some subset thereof).

So, finally, when I originally wrote the answer I wasn't thinking properly (I wouldn't go so far as to say that I was confused, as I hope I've just demonstrated I do know what I'm talking about when I actually think first, I just didn't think very much). The usual meaning of the dirac delta is not what is wanted here, but one of the points of my answer was that the input domain was not defined so the Kronecker delta would also not have been right. Thus the best mathematical answer (which I was aiming for) would have been the characteristic function.

I hope that that is all clear; and I also hope that I never have to write a mathematical piece again using HTML entities instead of TeX macros!

Andrew Stacey
  • 954
  • 6
  • 17
  • 37
    +1 - If I could downvote Quentin for not knowing the dirac_delta function I would. I would like to know which college he went to because I don't think I would hire anyone from there if they don't even know something that fundamental to digital processing. I would further downvote Quentin for his inability to grasp the bit of humor you were attempting. – Dunk Aug 03 '11 at 15:59
  • 1
    @Dunk: Thank you for restoring my faith in programmers! – Andrew Stacey Aug 03 '11 at 18:40
  • 23
    If I downvoted every answer I didn't understand... I would downvote a lot of answers. – Seamus Aug 04 '11 at 10:49
  • Andrew confuses the Dirac-Delta with the Kronecker-Delta. If I could downvote Dunk, I would downvote him for wanting to downvote others when he doesn't understand the delta-function himself. – Jakob Egger Aug 05 '11 at 09:11
  • 1
    Andrew is most certainly _not_ confused about delta functions. The Kronecker delta is most often used for _discrete_ domains and the Dirac for _continuous_. One can make a case that **the** Dirac delta function is the general delta function at 0, I guess, but it is quite standard to denote the translated Dirac delta by `\delta_a`. I merely transposed the subscript to an argument (since a subscript _is_ an argument in mathematics). One of the **points** of my answer was that the domain is not defined and therefore only the general delta function makes sense. – Andrew Stacey Aug 05 '11 at 09:28
  • I've just realised the source of Jakob's confusion. When the domain is not defined then the only sensible measure is the so-called _counting measure_ which gives each point measure 1. I should probably edit my answer to make this clear (as this comment is "below the fold") but life's too short. – Andrew Stacey Aug 05 '11 at 11:44
  • 2
    +1 for teaching me something new. I didn't know what dirac delta was...now I do :) I love stackoverflow! – bejonbee Aug 20 '11 at 15:14
  • But no, the dirac delta would set v to infinity at zero! – wrongusername Aug 22 '11 at 23:36
  • 4
    Hello Andrew, it's been a while. – Tim Down Aug 26 '11 at 12:23
  • 4
    @Tim: Good grief, so it has! And how is the Bishop of Bermuda? (Did I remember that right?) I guess this comment thread isn't the best place to catch up, though ... 17 years, isn't it? – Andrew Stacey Aug 26 '11 at 12:31
  • 1
    First of all thank you for teaching me about the functions, however, do you realize that without you actually implementing the `characteristic_function` it is the same as writing: `v=magic(v);`. This answer has failed at giving short and clear solution to what OP asked. `v=1-v;` is the best in my opinion. Programmer who knows math well is strong programmer, mathematician who knows math well is strong mathematician. – Cԃաԃ Jul 18 '13 at 02:02
  • 3
    @Cԃաԃ "This answer has failed... " *sigh*. You did read that I'm a mathematician, didn't you? This answer works perfectly for a spherical programmer in a vacuum so I don't know what you're complaining about. – Andrew Stacey Jul 18 '13 at 06:32
  • I'm sorry, I didn't know you were a mathematician. Now I understand why you have answered this way. – Cԃաԃ Jul 19 '13 at 00:25
  • 1
    @AndrewStacey is the programmer a frictionless infinite plane, as well? Because otherwise this is hogwash. – Mike G Oct 31 '13 at 17:41
  • gotta love stackoverflow. ty sir for your answer! – Takeshi Aug 14 '15 at 18:37
35

You could do

v = Math.abs(--v);

The decrement sets the value to 0 or -1, and then the Math.abs converts -1 to +1.

pimvdb
  • 141,012
  • 68
  • 291
  • 345
Paul
  • 928
  • 8
  • 17
  • 27
    This has turned into a 'Generate 10000 ways to do a simple task' competition. And I like all the ways haha. – Josh Aug 02 '11 at 12:45
  • 27
    `v = Math.round(Math.sin(Math.PI/(v+3)));` – Benoit Aug 02 '11 at 13:28
  • Curious: is the result of this statement well-defined? I.e. is it not possible that the side-effect of `--` will happen after the side-effect of `=`? (In which case the result of `Math.Abs()` would be clobbered.) I don't know how much the javascript spec constrains the order that side effects happen, so I'm just asking. – LarsH Aug 02 '11 at 14:22
  • Honestly I'm not entirely sure. Most languages are pretty specific that the prefixed decrement/increment operators take precedence, but I don't know specifically about javascript. When I first thought of this solution I didn't realize the question was tagged `javascript` but noticed that before I submitted. I checked to ensure that all the operations were valid but as far as the specific order of operations in js, I just can't be sure. – Paul Aug 02 '11 at 14:48
  • 15
    @Benoit - your formula equals 1 for both v=0 and v=1. **THIS** one is correct though! `v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));` :D – Teo.sk Aug 02 '11 at 15:54
  • I think you want `v = Math.Abs(-v);`. The side effect of the `--` just confuses things. – Keith Thompson Aug 03 '11 at 00:15
  • 2
    That would never change the value. If `v = 1` then `v = Math.Abs(-1)` which is +1. If `v = 0` then `v = Math.Abs(-0)` which is 0. – Paul Aug 03 '11 at 01:28
  • 1
    +1 And this was my other one... Grr. – recursive Aug 03 '11 at 04:36
34

in general whenever you need to toggle between two values , you can just subtract the current value from the sum of the two toggle values :

    0,1 -> v = 1 - v
    1,2 -> v = 3 - v
    4,5 -> v = 9 - v 
Mouna Cheikhna
  • 35,154
  • 10
  • 46
  • 68
  • 2
    This is interesting and creative but potentially dangerous. If `v` becomes corrupted it will suddenly start to toggle between two different values. (Just something to consider...) – oosterwal Aug 08 '11 at 17:46
  • 1
    +1 for the interesting idea. not that the OP or anyone else is actually going to use it in this circumstances, but this piece of info should exist somewhere in brain forever. – Shimmy Weitzhandler Nov 16 '11 at 03:04
  • 3
    @oosterwal: Then surely the issue lies with the corruption... – GManNickG Jul 30 '12 at 16:58
  • @GManNickG: Sooner or later data corruption will happen so we need to be aware of the consequence of not detecting it. If `v` is normally used to alternately execute two states from a list of three or more states, then a corruption of `v` could cause the program to alternately execute two completely different states--this could result in unexpected and undesirable results. The lesson to take away from this is: _Always perform plausibility checks on your data._ – oosterwal Nov 27 '12 at 22:53
33

If it must be the integer 1 or 0, then the way you're doing it is fine, though parentheses aren't needed. If these a are to be used as booleans, then you can just do:

v = !v;
Michael Berkowski
  • 253,311
  • 39
  • 421
  • 371
23
v = v == 0 ? 1 : 0;

Is enough !

nidhin
  • 5,783
  • 5
  • 29
  • 45
  • 7
    More of an opinion than an answer, don't you think? – Brian Aug 02 '11 at 11:28
  • 16
    @Brian: 'better' is all about opinion actually. – pimvdb Aug 02 '11 at 11:33
  • 3
    I like how you've taken the brackets out - that trims a couple of characters off! – Ollie Glass Aug 02 '11 at 11:36
  • 10
    @Brian: The "*answer*" is *"No, there isn't a better way of writing `v = (v==0 ? 1 : 0);`"*. Everyone else is finding different ways of playing golf; and not actually answering the question. That's why i up-voted this answer. – Ian Boyd Aug 02 '11 at 12:54
21

List of solutions

There are three solutions I would like to propose. All of them convert any value to 0 (if 1, true etc.) or 1 (if 0, false, null etc.):

  • v = 1*!v
  • v = +!v
  • v = ~~!v

and one additional, already mentioned, but clever and fast (although works only for 0s and 1s):

  • v = 1-v

Solution 1

You can use the following solution:

v = 1*!v

This will first convert the integer to the opposite boolean (0 to True and any other value to False), then will treat it as integer when multiplying by 1. As a result 0 will be converted to 1 and any other value to 0.

As a proof see this jsfiddle and provide any values you wish to test: jsfiddle.net/rH3g5/

The results are as follows:

  • -123 will convert to integer 0,
  • -10 will convert to integer 0,
  • -1 will convert to integer 0,
  • 0 will convert to integer 1,
  • 1 will convert to integer 0,
  • 2 will convert to integer 0,
  • 60 will convert to integer 0,

Solution 2

As mblase75 noted, jAndy had some other solution that works as mine:

v = +!v

It also first makes boolean from the original value, but uses + instead of 1* to convert it into integer. The result is exactly the same, but the notation is shorter.

Solution 3

The another approach is to use ~~ operator:

v = ~~!v

It is pretty uncommon and always converts to integer from boolean.

Tadeck
  • 117,059
  • 25
  • 140
  • 191
  • In JavaScript, you can prefix a variable with `+` to convert it to a number, so `+!v` is equivalent to your solution (jAndy's solution in the OP's comments). – Blazemonger Oct 14 '11 at 21:12
  • @mblase75: Yes, you are right that `1*` can be replaced by `+` when trying to convert boolean into integer. Everything else in my answer remains the same. jAndy's answer is correct, but mine is more detailed. I will add his/her solution to my answer. – Tadeck Oct 15 '11 at 18:41
  • @Tadeck +1 for the nice idea. – Shimmy Weitzhandler Nov 16 '11 at 03:05
17

To sum up another answer, a comment and my own opinion, I suggest combining two things:

  1. Use a function for the toggle
  2. Inside this function use a more readable implementation

Here is the function which you could place in a library or maybe wrap it in a Plugin for another Javascript Framework.

function inv(i) {
  if (i == 0) {
    return 1
  } else {
    return 0;
  }
}

And the usage is simply:

v = inv(v);

The advantages are:

  1. No code Duplication
  2. If you or anybody read this again in the future, you will understand your code in a minimum of time.
Martin Schlagnitweit
  • 1,889
  • 5
  • 23
  • 40
13

This is missing:

v = [1, 0][v];

It works as round robin as well:

v = [2, 0, 1][v]; // 0 2 1 0 ...
v = [1, 2, 0][v]; // 0 1 2 0 ...
v = [1, 2, 3, 4, 5, 0][v]; // 0 1 2 3 4 5 ...
v = [5, 0, 1, 2, 3, 4][v]; // 0 5 4 3 2 1 0 ...

Or

v = {0: 1, 1: 0}[v];

The charme of the last solution, it works with all other values as well.

v = {777: 'seven', 'seven': 777}[v];

For a very special case, like to get a (changing) value and undefined, this pattern may be helpful:

v = { undefined: someValue }[v]; // undefined someValue undefined someValue undefined ...
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324
  • Can you explain the answer, possibly with jsfiddle (or equivalent)? – Phalgun Jan 16 '21 at 18:12
  • @Phalgun, what part? you may try it yourself ... – Nina Scholz Jan 16 '21 at 18:13
  • I am trying to plug some number to test it. For example, consider `v = 7`, then with OP's answer `v = (v == 0 ? 1 : 0)`, v is 0. Now, with `v = [1, 0][v]`, v is undefined. I think I am missing something here. – Phalgun Jan 16 '21 at 18:20
  • 1
    you need to declare `v` and take a value of either `0` or `1`. – Nina Scholz Jan 16 '21 at 18:22
  • Ah! Got it. So we are declaring an array of 2 values and using the value of variable v as the index to get the desired value. I think it can be expanded to be generic with slight modification `let v = 0; v = [1, 0][+!!v]; console.log(v);` – Phalgun Jan 16 '21 at 18:29
  • 1
    not really. if you take `+!v` (as in the answer [below](https://stackoverflow.com/a/13544271/1447675)), you need no more an array , because you got the value already. in my example `v` is used without converting to another value or type. – Nina Scholz Jan 16 '21 at 18:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/227421/discussion-between-phalgun-and-nina-scholz). – Phalgun Jan 16 '21 at 18:37
13

I don't know why you want to build your own booleans? I like the funky syntaxes, but why not write understandable code?

This is not the shortest/fastest, but the most clearest (and readable for everyone) is using the well-known if/else state:

if (v === 0)
{
  v = 1;
}
else
{
  v = 0;
}

If you want to be really clear, you should use booleans instead of numbers for this. They are fast enough for most cases. With booleans, you could just use this syntax, which will win in shortness:

v = !v;
c69
  • 16,477
  • 6
  • 47
  • 78
Mark Knol
  • 7,885
  • 3
  • 26
  • 43
  • 1
    This would actually be my preferred answer; but **ternary operator** vs **if-else** is a holy war i didn't want to light the fuse on. That said, i think the first line should be `=== 0`. With sample input of `7`, the correct output is `0`, but this will output `1`. – Ian Boyd Aug 02 '11 at 22:28
  • 4
    Is there value to silently correcting an input like 7 instead of throwing an exception of some kind? I mean what if some other bit of code got it's hands on the 7 when it was expecting 0 or 1 only, before your code corrected the value? – Chuck van der Linden Aug 03 '11 at 08:53
12

Another form of your original solution:

v = Number(v == 0);

EDIT: Thanks TehShrike and Guffa for pointing out the error in my original solution.

Kurt Kaylor
  • 2,672
  • 12
  • 18
  • 4
    The == operator returns a boolean (instead of an integer) under many systems. This would only work if v was defined as an integer, and the language was cool with automatic casting from boolean to integer. – TehShrike Aug 02 '11 at 20:48
  • Very true. I was answering the question in the context of javascript (how the question was tagged). – Kurt Kaylor Aug 03 '11 at 15:40
  • @Kurt Kaylor: Javascript is one of the systems where the == operator returns a boolean, so it doesn't do the same as the original solution. – Guffa Aug 03 '11 at 16:20
  • @Guffa: I am taking advantage of the fact that javascript is a weakly typed language with implicit type conversion (e.g.'0.0000' == 0, 0 == "", false == "", false == 0, 1 == true, etc). I can use the returned boolean value in the same way as I can use an integer of value 0 or 1. Try, for example, to evaluate "2 + true" in a javascript console, you'll get 3. – Kurt Kaylor Aug 03 '11 at 18:42
  • 1
    @Kurt Kaylor: That only works in situations where you force an implicit conversion. Try for example `'opacity:'+true` and you end up with `opacity:true` instead of `opacity:1`. – Guffa Aug 03 '11 at 18:45
  • @Guffa: Good point, I didn't consider that. Updating answer. – Kurt Kaylor Aug 03 '11 at 18:54
11

I would make it more explicit.

What does v mean?

For example when v is some state. Create an object Status. In DDD an value object.

Implement the logic in this value object. Then you can write your code in a more functional way which is more readable. Switching status can be done by creating a new Status based on the current status. Your if statement / logic is then encapsulated in your object, which you can unittest. An valueObject is always immutable, so it has no identity. So for changing it's value you have to create a new one.

Example:

public class Status
{
    private readonly int _actualValue;
    public Status(int value)
    {
        _actualValue = value;
    }
    public Status(Status status)
    {
        _actualValue = status._actualValue == 0 ? 1 : 0; 
    }

    //some equals method to compare two Status objects
}

var status = new Status(0);

Status = new Status(status);
Marco
  • 3,936
  • 3
  • 27
  • 60
10

Another way to do it:

v = ~(v|-v) >>> 31;
Eng.Fouad
  • 107,075
  • 62
  • 298
  • 390
9

Since this is JavaScript, we can use the unary + to convert to int:

v = +!v;

This will logical NOT the value of v (giving true if v == 0 or false if v == 1). Then we convert the returned boolean value into its corresponding integer representation.

0x499602D2
  • 87,005
  • 36
  • 149
  • 233
8

Just for kicks: v = Math.pow(v-1,v) also toggles between 1 and 0.

Blazemonger
  • 82,329
  • 24
  • 132
  • 176
7

define an array{1,0}, set v to v[v], therefore v with a value of 0 becomes 1, and vica versa.

S..
  • 4,821
  • 1
  • 32
  • 39
  • My solution is correct, if you don't like it, write why. Your comment helps nobody. My solution reads a variable, as opposed to making a decision. This requires less CPU. – S.. Sep 07 '12 at 15:23
7

One more: v=++v%2

(in C it would be simple ++v%=2)

ps. Yeah, I know it's double assignment, but this is just raw rewrite of C's method (which doesn't work as is, cause JS pre-increment operator dosen't return lvalue.

Adam Jurczyk
  • 2,123
  • 11
  • 16
  • 3
    Your C version is illegal; you can't modify the result of a `++` operator (it's not an lvalue). As for `v=++v%2`, you're modifying `v` twice. I don't know whether that's well defined in JavaScript , but it's not necessary. `v = (v+1) % 2`. – Keith Thompson Aug 03 '11 at 00:18
  • At least in `c++` it is - because pre-incrementation operator has higher priority and modifies variable 'in place', so it can be used as lvalue. I think that JS implementation of `++` is such that it cant be treated as an lvalue:/ And yeas, this is redundant, but i was trying to show just another method - there are already posted better solutions :) – Adam Jurczyk Aug 03 '11 at 08:00
  • 3
    +1. Can be written as v = (v+1)%2. – niktrs Aug 03 '11 at 12:16
7

If you're guaranteed your input is either a 1 or a 0, then you could use:

v = 2+~v;
brandx
  • 1,003
  • 12
  • 10
5

Another creative way of doing it, with v being equal to any value, will always return 0 or 1

v = !!v^1;
Yanick Rochon
  • 45,203
  • 21
  • 112
  • 182
  • 3
    two `!!` result in nothing in logical maths, you can put `!!!!` in there and will be same but resulting 4 unneed operations – Alex K Aug 03 '11 at 08:35
  • 10
    @Alex: `!!` will cast to a bool. `!!(1) === true` and `!!(0) === false` – nickf Aug 03 '11 at 09:10
  • 1
    @nickf: aha, so i guess `v = Boolean(v^1)` would be more informational, thanks for explaining - didn't thought about casting – Alex K Aug 03 '11 at 12:34
  • 1
    @Alex, "logical maths"? This is why mathematicians are poor programmers. Don't get me wrong; good programmers are also good at understanding mathematics. But this has nothing to do with logical maths. It's a language construct that, given any expression, at least in Javascript, `!` will cast it into boolean. Adding another `!` will negate that boolean. The casting is implicit here, and the end result works. There is no need for the -1. – Yanick Rochon Aug 03 '11 at 12:44
  • 1
    i'm not a mathematician at all. you can try this and see yourself http://jsperf.com/javascript-boolean-test – Alex K Aug 03 '11 at 13:36
  • @Alex, I said it was "creative", I didn't say it was optimal or not even the best solution. – Yanick Rochon Aug 03 '11 at 14:30
  • @Yanick, not saying that either :) just trying to tell people not to do more operations than should be :) – Alex K Aug 03 '11 at 17:07
4

If possible values for v are only 0 and 1, then for any integer x, the expression: v = Math.pow((Math.pow(x, v) - x), v); will toggle the value.

I know this is an ugly solution and the OP was not looking for this...but I was thinking about just another solution when I was in the loo :P

Amit
  • 446
  • 6
  • 11
3

Untested, but if you're after a boolean I think var v = !v will work.

Reference: http://www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables

Martin Bean
  • 33,901
  • 20
  • 114
  • 183
3
v=!v;

will work for v=0 and v=1; and toggle the state;

teacher
  • 965
  • 3
  • 14
  • 27
1

If there are just two values, as in this case(0, 1), i believe it's wasteful to use int. Rather go for boolean and work in bits. I know I'm assuming but in case of toggle between two states boolean seems to be ideal choice.

Amber
  • 290
  • 1
  • 3
  • 10
0

Well, As we know that in javascript only that Boolean comparison will also give you expected result.

i.e. v = v == 0 is enough for that.

Below is the code for that:

var v = 0;
alert("if v  is 0 output: " + (v == 0));

setTimeout(function() {
  v = 1;
  alert("if v  is 1 Output: " + (v == 0));
}, 1000);

JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/

Hoping this will help you :)

ankitkanojia
  • 2,872
  • 4
  • 18
  • 30
Vikash Pandey
  • 5,073
  • 6
  • 36
  • 41
  • That works for toggling a value, but the value doesn't toggle between 0 and 1, but rather between `true`and `false`. You can use `v == 0` to determine the value of the variable in a condition, but if you want to use the value 0 or 1 you would need to use something like `v == 0 ? 0 : 1` or `Number(v)` to get that. (Also, you can use `v = !v;` to toggle between `true` and `false`.) – Guffa Oct 04 '16 at 10:21
  • yeah got it.. thank you :) – Vikash Pandey Oct 04 '16 at 11:59
0

v = Number(!v)

It will type cast the Inverted Boolean value to Number, which is the desired output.

Rohit Goyal
  • 194
  • 1
  • 1
  • 7
-3
v = !v * 1

multiplying by 1 to turn boolean into number

JVM
  • 690
  • 1
  • 6
  • 22