Which construct is better suited for this situation, an if-else or a switch?

Go To StackoverFlow.com

1

Which construct is better suited for this situation, an if-else or a switch?

- (id)hexEvaluator:(double)remainder
{
    if(remainder == 0) {return [NSNumber numberWithInt:0];}
    else if(remainder == 1) {return [NSNumber numberWithInt:1];}
    else if(remainder == 2) {return [NSNumber numberWithInt:2];}
    else if(remainder == 3) {return [NSNumber numberWithInt:3];}
    else if(remainder == 4) {return [NSNumber numberWithInt:4];}
    else if(remainder == 5) {return [NSNumber numberWithInt:5];}
    else if(remainder == 6) {return [NSNumber numberWithInt:6];}
    else if(remainder == 7) {return [NSNumber numberWithInt:7];}
    else if(remainder == 8) {return [NSNumber numberWithInt:8];}
    else if(remainder == 9) {return [NSNumber numberWithInt:9];}
    else if(remainder == 10) {return @"A";}
    else if(remainder == 11) {return @"B";}
    else if(remainder == 12) {return @"C";}
    else if(remainder == 13) {return @"D";}
    else if(remainder == 14) {return @"E";}
    else if(remainder == 15) {return @"F";}
    else return nil;

    switch ((int)remainder) 
    {
        case 0:  return [NSNumber numberWithInt:0]; break;
        case 1:  return [NSNumber numberWithInt:1]; break;
        case 2:  return [NSNumber numberWithInt:2]; break;
        case 3:  return [NSNumber numberWithInt:3]; break;
        case 4:  return [NSNumber numberWithInt:4]; break;
        case 5:  return [NSNumber numberWithInt:5]; break;
        case 6:  return [NSNumber numberWithInt:6]; break;
        case 7:  return [NSNumber numberWithInt:7]; break;
        case 8:  return [NSNumber numberWithInt:8]; break;
        case 9:  return [NSNumber numberWithInt:9]; break;
        case 10: return @"A";; break;
        case 11: return @"B";; break;
        case 12: return @"C";; break;
        case 13: return @"D";; break;
        case 14: return @"E";; break;
        case 15: return @"F";; break;

        default: return nil; break;
    }
}

Also, on a side note: why is the switch expression (in my case remainder) not allowed to be of type 'double'? I had to cast it to an 'int' for it to compile.

2012-04-03 20:09
by Joey
Because that's what a switch statement is expecting -- an int - jmstone617 2012-04-03 20:11


5

Definitely an if statement. And I would get rid of all the extra lines:

- (id)hexEvaluator:(double)remainder
{
    if (remainder < 10)
    {
        return [NSNumber numberWithInt:(int)remainder];
    }
    else if (remainder < 16)
    {
        return [NSString stringWithFormat:@"%X", (int)remainder)];
    }
    return nil;
}
2012-04-03 20:20
by e.James
Thank you e.james, that is definitely more concise and simplistic. I have never seen the @"%X" formatting, can you explain how it works - Joey 2012-04-03 20:44
'%X' is one of the standard NSString format specifiers. It tells NSString to covert the integer argument into (uppercase) hexadecimal. See: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.htm - e.James 2012-04-03 21:42


3

In short: an if-statement is better suited for this situation since it offer more complex conditions.


Sample code

In your case the sample code could replace the functionality of your method:

if (remainder < 10 ) {
    return [NSNumber numberWithInt:(int)reminder]; 
} else if (remainder < 16) {
    // Will return: "A", "B", "C", "D", "E" or "F"
    return [NSString stringWithFormat:@"%X", (int)remainder];
} else {
    return nil;
}

There are other ways to transform a base ten int to a hex value and by using either %x (for small letters) or %X (for big letters) you can get the hex value as a string. Simple


Other solutions

Depending on how you are using the result of you calculation you may be able to refactor and make even better code.

If you are only using the result (number or string) to display to the user then your NSNumbers could probably be replaced with NSStrings as well and the first if statement could be removed:

if (remainder < 16) {
    // Will return: "1", "2", "3", "4", ...,  "A", "B", "C", "D", "E" or "F"
    return [NSString stringWithFormat:@"%X", (int)remainder]; 
} else {
    return nil;
}

If on the other hand you are using the result for some calculation than you should probably look into using a data type that is easier to compare (how are you comparing [NSNumber numberWithInt:9] with @"A"?)

Maybe use hex values directly in code like this:

int hex = 0xC;
NSLog(@"hex = %X", hex); // Output: hex = C
NSLog(@"int = %d", hex); // Output: hex = 12

That makes comparisons much easier:

NSLog(@"%@ than 9", (hex > 0x9 ? @"bigger" : @"smaller")); // bigger than 9
NSLog(@"%@ than F", (hex > 0xF ? @"bigger" : @"smaller")); // smaller than F

Depending on how you refactor your code you should probably rename it to more clearly speak you intent.

2012-04-03 20:17
by David Rönnqvist


0

It cant be a double because your cases are labeled with int's and its a type mismatch.

Although the switch looks better I believe the if statements with the { } removed are better. That way there is only one statement per line and all good practices are maintained.

2012-04-03 20:12
by RyanS
However someone else may have to speak to the load caused by the multiple checks caused by the if statements versus the switch. (I dont know if the cases are indexed or iterated - RyanS 2012-04-03 20:14


0

This might help

- (id)hexEvaluator:(double)remainder
{
    return remainder <= 9 ? [NSNumber numberWithInt:(int)remainder] : [NSString stringWithFormat:@"%X", (int)remainder)]; 
}
2012-04-03 20:23
by Nilesh