Может ли Objective-C включить NSString?
Есть ли более разумный способ переписать это?
if ([cardName isEqualToString:@"Six"]) {
[self setValue:6];
} else if ([cardName isEqualToString:@"Seven"]) {
[self setValue:7];
} else if ([cardName isEqualToString:@"Eight"]) {
[self setValue:8];
} else if ([cardName isEqualToString:@"Nine"]) {
[self setValue:9];
}
Ответы
Ответ 1
К сожалению, они не могут. Это одно из лучших и наиболее востребованных применений операторов switch, так что, надеюсь, они прыгают на (сейчас) Java (и другие) подножку!
Если вы делаете имена карт, возможно, назначьте каждому объекту карты целое значение и включите его. Или, возможно, перечисление, которое считается числом и поэтому может быть включено.
например.
typedef enum{
Ace, Two, Three, Four, Five ... Jack, Queen, King
} CardType;
Сделанный таким образом, Ace будет равен случаю 0, два как случай 1 и т.д.
Ответ 2
Вы можете создать словарь блоков, например:
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
Чтобы иметь раздел "по умолчанию", замените последнюю строку следующим образом:
CaseBlock c = d[lookup];
if (c) c(); else { NSLog(@"Joker"); }
Надеюсь, Apple научит "переключать" несколько новых трюков.
Ответ 3
Для меня приятный простой способ:
NSString *theString = @"item3"; // The one we want to switch on
NSArray *items = @[@"item1", @"item2", @"item3"];
int item = [items indexOfObject:theString];
switch (item) {
case 0:
// Item 1
break;
case 1:
// Item 2
break;
case 2:
// Item 3
break;
default:
break;
}
Ответ 4
К сожалению, операторы switch могут использоваться только для примитивных типов. Однако у вас есть несколько вариантов с помощью коллекций.
Вероятно, лучшим вариантом было бы сохранить каждое значение в качестве записи в NSDictionary.
NSDictionary *stringToNumber = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:6],@"Six",
[NSNumber numberWithInt:7],@"Seven",
[NSNumber numberWithInt:8],@"Eight",
[NSNumber numberWithInt:9],@"Nine",
nil];
NSNumber *number = [stringToNumber objectForKey:cardName];
if(number) [self setValue:[number intValue]];
Ответ 5
Есть и другие способы сделать это, но switch
не является одним из них.
Если у вас есть только несколько строк, как в вашем примере, у вас есть хороший код. Если у вас много случаев, вы можете хранить строки как ключи в словаре и искать соответствующее значение:
NSDictionary *cases = @{@"Six" : @6,
@"Seven" : @7,
//...
};
NSNumber *value = [cases objectForKey:cardName];
if (value != nil) {
[self setValue:[value intValue]];
}
Ответ 6
Вот более разумный способ написать это. Чтобы использовать NSNumberFormatter
в "стиль написания" :
NSString *cardName = ...;
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterSpellOutStyle];
NSNumber *n = [nf numberFromString:[cardName lowercaseString]];
[self setValue:[n intValue]];
[nf release];
Обратите внимание, что число форматера хочет, чтобы строка была уменьшена, поэтому мы должны сделать это сами, прежде чем передавать ее в форматтер.
Ответ 7
Objective-c ничем не отличается от c в этом аспекте, он может включать только то, что может c (и preproc def, как NSInteger, NSUInteger, поскольку они в конечном счете просто типизированы для целочисленного типа).
Википедия:
c синтаксис:
Оператор switch приводит к тому, что управление передается одному из нескольких операторов в зависимости от значения выражения, которое должно иметь интегральный тип.
Интегральные типы:
В информатике целое число является базовым типом целочисленного типа данных, a тип данных, который представляет собой некоторое конечное подмножество математического целые числа. Интегральные типы данных могут быть разных размеров и могут или могут не допускается содержать отрицательные значения.
Ответ 8
BY FAR.. мой ИЗБРАННОЕ "Надстройка ObjC" ObjectMatcher
objswitch(someObject)
objcase(@"one") { // Nesting works.
objswitch(@"b")
objcase(@"a") printf("one/a");
objcase(@"b") printf("one/b");
endswitch // Any code can go here, including break/continue/return.
}
objcase(@"two") printf("It TWO."); // Can omit braces.
objcase(@"three", // Can have multiple values in one case.
nil, // nil can be a "case" value.
[self self], // "Case" values don't have to be constants.
@"tres", @"trois") { printf("It a THREE."); }
defaultcase printf("None of the above."); // Optional default must be at end.
endswitch
И он работает с не-строками, TOO... в циклах, даже!
for (id ifNumericWhatIsIt in @[@99, @0, @"shnitzel"])
objswitch(ifNumericWhatIsIt)
objkind(NSNumber) printf("It a NUMBER.... ");
objswitch([ifNumericWhatIsIt stringValue])
objcase(@"3") printf("It THREE.\n");
objcase(@"99") printf("It NINETY-NINE.\n");
defaultcase printf("some other Number.\n");
endswitch
defaultcase printf("It something else entirely.\n");
endswitch
It a NUMBER.... It NINETY-NINE.
It a NUMBER.... some other Number.
It something else entirely.
Лучше всего, что SO немногие {...}
, :
и ()
Ответ 9
Немного поздно, но для любого в будущем я смог заставить это работать для меня
#define CASE(str) if ([__s__ isEqualToString:(str)])
#define SWITCH(s) for (NSString *__s__ = (s); ; )
#define DEFAULT
Ответ 10
Я опаздываю на вечеринку, но, чтобы ответить на вопрос, как указано, есть более интеллектуальный способ:
NSInteger index = [@[@"Six", @"Seven", @"Eight", @"Nine"] indexOfObject:cardName];
if (index != NSNotFound) [self setValue: index + 6];
Обратите внимание, что indexOfObject
будет искать совпадение с помощью isEqual:
, точно так же, как в вопросе.
Ответ 11
Я не могу комментировать cris-ответ на @Cris, но я бы хотел сказать, что:
Существует метод LIMITATION для @cris:
typedef enum не будет принимать буквенно-цифровые значения
typedef enum
{
12Ace, 23Two, 23Three, 23Four, F22ive ... Jack, Queen, King
} CardType;
Итак, вот еще один:
Связать стек над потоком Перейти к этому пользовательскому ответу "user1717750"
Ответ 12
Основываясь на идее @Graham Perks, опубликованной ранее, спроектировал простой класс, чтобы сделать чередование строк довольно простым и чистым.
@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
Вы бы использовали его следующим образом:
[Switcher switchOnString:someString
using:@{
@"Spades":
^{
NSLog(@"Spades block");
},
@"Hearts":
^{
NSLog(@"Hearts block");
},
@"Clubs":
^{
NSLog(@"Clubs block");
},
@"Diamonds":
^{
NSLog(@"Diamonds block");
}
} withDefault:
^{
NSLog(@"Default block");
}
];
Правильный блок будет выполняться в соответствии со строкой.
Gist для этого решения
Ответ 13
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;
}
}
Наслаждайтесь кодированием.....