Is there a more intelligent way to rewrite this?
if ([cardName isEqualToString:@\"Six\"]) {
[self setValue:6];
} else if ([cardName isEqualToString:@\"Se
You could set up a dictionary of blocks, like this:
NSString *lookup = @"Hearts"; // The value you want to switch on
typedef void (^CaseBlock)();
// Squint and this looks like a proper switch!
NSDictionary *d = @{
@"Diamonds":
^{
NSLog(@"Riches!");
},
@"Hearts":
^{
self.hearts++;
NSLog(@"Hearts!");
},
@"Clubs":
^{
NSLog(@"Late night coding > late night dancing");
},
@"Spades":
^{
NSLog(@"I'm digging it");
}
};
((CaseBlock)d[lookup])(); // invoke the correct block of code
To have a 'default' section, replace the last line with:
CaseBlock c = d[lookup];
if (c) c(); else { NSLog(@"Joker"); }
Hopefully Apple will teach 'switch' a few new tricks.
Unfortunately they cannot. This is one of the best and most sought after utilizations of switch statements, so hopefully they hop on the (now) Java (and others) bandwagon!
If you are doing card names, perhaps assign each card object an integer value and switch on that. Or perhaps an enum, which is considered as a number and can therefore be switched upon.
e.g.
typedef enum{
Ace, Two, Three, Four, Five ... Jack, Queen, King
} CardType;
Done this way, Ace would be be equal to case 0, Two as case 1, etc.
Objective-c is no different from c in this aspect, it can only switch on what c can (and the preproc def's like NSInteger, NSUInteger, since they ultimately are just typedef'd to an integral type).
Wikipedia:
c syntax:
The switch statement causes control to be transferred to one of several statements depending on the value of an expression, which must have integral type.
Integral Types:
In computer science, an integer is a datum of integral data type, a data type which represents some finite subset of the mathematical integers. Integral data types may be of different sizes and may or may not be allowed to contain negative values.
You can use macros approach to achieve it:
#define CASE(str) if ([__s__ isEqualToString:(str)])
#define SWITCH(s) for (NSString *__s__ = (s); ; )
#define DEFAULT
SWITCH (string) {
CASE (@"AAA") {
break;
}
CASE (@"BBB") {
break;
}
CASE (@"CCC") {
break;
}
DEFAULT {
break;
}
}
typedef enum
{
Six,
Seven,
Eight
} cardName;
- (void) switchcardName:(NSString *) param {
switch([[cases objectForKey:param] intValue]) {
case Six:
NSLog(@"Six");
break;
case Seven:
NSLog(@"Seven");
break;
case Eight:
NSLog(@"Eight");
break;
default:
NSLog(@"Default");
break;
}
}
Enjoy Coding.....
Building on @Graham Perks idea posted earlier, designed a simple class to make switching on strings fairly simple and clean.
@interface Switcher : NSObject
+ (void)switchOnString:(NSString *)tString
using:(NSDictionary<NSString *, CaseBlock> *)tCases
withDefault:(CaseBlock)tDefaultBlock;
@end
@implementation Switcher
+ (void)switchOnString:(NSString *)tString
using:(NSDictionary<NSString *, CaseBlock> *)tCases
withDefault:(CaseBlock)tDefaultBlock
{
CaseBlock blockToExecute = tCases[tString];
if (blockToExecute) {
blockToExecute();
} else {
tDefaultBlock();
}
}
@end
You would use it like this:
[Switcher switchOnString:someString
using:@{
@"Spades":
^{
NSLog(@"Spades block");
},
@"Hearts":
^{
NSLog(@"Hearts block");
},
@"Clubs":
^{
NSLog(@"Clubs block");
},
@"Diamonds":
^{
NSLog(@"Diamonds block");
}
} withDefault:
^{
NSLog(@"Default block");
}
];
The correct block will execute according to the string.
Gist for this solution