22

Is there a way to put a condition that return true only if one of the two component return true?

BOOL var1
BOOL var2

something shorter than if((var1 && !var2) || (!var1 && var2))

Thank you

Ishu
  • 12,797
  • 5
  • 35
  • 51
Nicolas Manzini
  • 8,379
  • 6
  • 63
  • 81

6 Answers6

55

As Objective-C is a superset of C, you simply use the XOR operator from C, which is ^.

Cyrille
  • 25,014
  • 12
  • 67
  • 90
  • 25
    That's the bitwise XOR, if you want a logical XOR, simply use `!=`. – Gabriele Petronella Apr 24 '13 at 21:52
  • 2
    Neither solution will work all the time. A BOOL can be any integer. Both will fail if both values are non-zero, but unequal. The most robust option is probably to write it out in full, like the original question. – Drew McCormack Nov 06 '14 at 10:01
  • 2
    @DrewMcCormack, to avoid this problem you can convert any type to real `BOOL` using two exclamation marks. `!!var1 != !!var2` – DanSkeel Feb 08 '16 at 10:11
45

XOR

if(!!var1 != !!var2)
{
   NSLog(@"XOR condition");
}

Exclamation marks convert vars to BOOL (real conversion, not casting)
So this solution works even if your variables are not BOOL.

!!(0|nil) ≡ 0  
!!(any other number|object) ≡ 1

This is useful in cases when you want to be sure that only one of vars is nonnil.

DanSkeel
  • 3,853
  • 35
  • 54
Ishu
  • 12,797
  • 5
  • 35
  • 51
  • short, elegant, easy and simple – meronix Jul 11 '12 at 11:59
  • By default BOOL variable is NO. In this condition, i think it is fail. Check it – Prasad G Jul 11 '12 at 12:06
  • I like this one btw but the carrot may be more academic thank for the answer – Nicolas Manzini Jul 11 '12 at 12:08
  • @Prasad G, By default bool variables are No. what the effect of that. xor condition TRUE,TRUE and False, false both condition gives False and True,False and False,TRUE gives True result. so where is the problem in above condition. – Ishu Jul 11 '12 at 12:18
  • @Ishu: Yes. You are right but when bool variables are default it shows XOR condition. whenever we assign NO to variables, there is no problem – Prasad G Jul 11 '12 at 12:35
  • @prasadG , BOOL a,b; if(a!=b) { NSLog(@"XOR"); } //this code also not give me the wrong answer for default values – Ishu Jul 11 '12 at 12:38
  • @Ishu: I have same problem. I don't know what happened to me. – Prasad G Jul 11 '12 at 12:45
  • You should be vigilant. Hold in mind, that if `var1 = string.length` or `var2 = mask | BitMaskConstant` it wouldn't work. – Zapko Oct 15 '14 at 14:51
3

You could add more clearness to the code that Ishu suggests by doing this:

#define XOR !=

and then you just write:

if (var1 XOR var2) {

    ...
}

truth table output:
[T XOR T => F; T != T => F],
[T XOR F => T; T != F => T],
[F XOR T => T; F != T => T] and
[F XOR F => F; F != F => F]

Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195
Lukas Kalinski
  • 2,213
  • 24
  • 26
  • @AlbertRenshaw Yes it is, because it results in the same truth table: [T XOR T => F; T != T => F], [T XOR F => T; T != F => T], [F XOR T => T; F != T => T] and [F XOR F => F; F != F => F]. – Lukas Kalinski Feb 10 '16 at 22:35
  • 1
    Woah you're right. I actually feel very foolish for not realizing this! Thank you for teaching me – Albert Renshaw Feb 11 '16 at 00:38
2

A macro could be an option. It will keep the same behaviour, but now in a more readable way.

#define XOR(x,y) (((x) && !(y)) || (!(x) && (y)))

if(XOR(var1, var2) {

}
Danilo Gomes
  • 767
  • 5
  • 15
0

try (int)var1 ^ (int)var2 YES and NO are actually defined as following:

#define YES (BOOL)1
#define NO  (BOOL)0
Cyrille
  • 25,014
  • 12
  • 67
  • 90
fvwmer
  • 191
  • 4
0
if ((!var1)==var2) 
{
        NSLog(@"Yes");
}
Prasad G
  • 6,702
  • 7
  • 42
  • 65