Czy Objective-C może włączyć NSString?

Czy istnieje bardziej inteligentny sposób na przepisanie tego?

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];
} 
Author: JAM, 2011-11-17

13 answers

Niestety nie mogą. Jest to jeden z najlepszych i najbardziej poszukiwanych sposobów wykorzystania instrukcji switch, więc miejmy nadzieję, że wskoczą na (teraz) modę Javy (i inne)!

Jeśli robisz nazwy kart, być może Przypisz każdemu obiektowi karty wartość całkowitą i włącz ją. A może enum, które jest uważane za liczbę i dlatego można je włączyć.

Np.

typedef enum{
  Ace, Two, Three, Four, Five ... Jack, Queen, King

} CardType;

W ten sposób as będzie równy case 0, dwa jako case 1, itd.

 137
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 03:30:25

Możesz skonfigurować słownik bloków, jak to:

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

Aby mieć sekcję "domyślną", zamień ostatnią linię na:

CaseBlock c = d[lookup];
if (c) c(); else { NSLog(@"Joker"); }

Mam nadzieję, że Apple nauczy "switch" kilka nowych sztuczek.

 114
Author: Graham Perks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-10 14:55:41

Dla mnie miły, łatwy sposób:

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;
}
 71
Author: sbonkosky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 01:46:43

Niestety, polecenia switch mogą być używane tylko na typach prymitywnych. Masz jednak kilka opcji korzystania z kolekcji.

Prawdopodobnie najlepszym rozwiązaniem byłoby przechowywanie każdej wartości jako wpisu w 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]];
 9
Author: ughoavgfhw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 03:34:18

Tutaj jest bardziej inteligentny sposób, aby to napisać. Jest to użycie NSNumberFormatter w "stylu wymowy":

NSString *cardName = ...;

NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterSpellOutStyle];
NSNumber *n = [nf numberFromString:[cardName lowercaseString]];
[self setValue:[n intValue]];
[nf release];

Zauważ, że program do formatowania liczb chce, aby łańcuch znaków był pisany małymi literami, więc musimy to zrobić sami przed przekazaniem go do formatatora.

 6
Author: Dave DeLong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 04:10:36

Są na to inne sposoby, ale nie jest jednym z nich.

Jeśli masz tylko kilka ciągów, jak w twoim przykładzie, kod, który masz, jest w porządku. Jeśli masz wiele przypadków, możesz zapisać ciągi jako klucze w Słowniku i wyszukać odpowiednią wartość:

NSDictionary *cases = @{@"Six" : @6,
                        @"Seven" : @7,
                        //...
                       };

NSNumber *value = [cases objectForKey:cardName];
if (value != nil) {
    [self setValue:[value intValue]];
}
 6
Author: Caleb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-21 21:58:47

Trochę za późno, ale dla każdego w przyszłości udało mi się to zrobić dla mnie

#define CASE(str) if ([__s__ isEqualToString:(str)])
#define SWITCH(s) for (NSString *__s__ = (s); ; )
#define DEFAULT
 5
Author: Newyork167,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-14 20:00:06

Objective - C nie różni się od c w tym aspekcie, może tylko włączyć to, co może c (i preproc def jest jak NSInteger, NSUInteger, ponieważ ostatecznie są one po prostu wpisane do typu całkowego).

Wikipedia:

Składnia C :

Polecenie switch powoduje przeniesienie sterowania do jednej z kilku instrukcji w zależności od wartości wyrażenia, które musi mieć typ całkowy .

Integral Typy :

W informatyce liczba całkowita jest punktem odniesienia typu danych integral, a typ danych, który reprezentuje pewien skończony podzbiór matematyczny liczby całkowite. Integralne typy danych mogą mieć różną wielkość i mogą nie mogą zawierać wartości ujemnych.

 3
Author: chown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 03:35:38

ZDECYDOWANIE.. moim ulubionym "dodatkiem ObjC" jest 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's 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's a THREE."); }
    defaultcase printf("None of the above."); // Optional default must be at end.
endswitch

I działa również z nie-ciągami... nawet w pętlach!

for (id ifNumericWhatIsIt in @[@99, @0, @"shnitzel"])
    objswitch(ifNumericWhatIsIt)
        objkind(NSNumber)  printf("It's a NUMBER.... "); 
        objswitch([ifNumericWhatIsIt stringValue])
            objcase(@"3")   printf("It's THREE.\n"); 
            objcase(@"99")  printf("It's NINETY-NINE.\n"); 
            defaultcase     printf("some other Number.\n");
       endswitch
    defaultcase printf("It's something else entirely.\n");
endswitch

It's a NUMBER.... It's NINETY-NINE.
It's a NUMBER.... some other Number.
It's something else entirely.

Najlepszy ze wszystkich, jest tak mało {...} 'S, :' S, i () ' s

 3
Author: Alex Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 15:56:00

Jestem trochę spóźniony na imprezę, ale aby odpowiedzieć na pytanie, jak stwierdzono, jest bardziej inteligentny sposób:

NSInteger index = [@[@"Six", @"Seven", @"Eight", @"Nine"] indexOfObject:cardName];
if (index != NSNotFound) [self setValue: index + 6];

Zauważ, że indexOfObject będzie szukał dopasowania za pomocą isEqual:, Dokładnie tak, jak w pytaniu.

 1
Author: ilya n.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-05 10:08:37

Nie mogę skomentować odpowiedzi cris na @Cris odpowiedz, ale chciałbym powiedzieć, że:

Istnieje ograniczenie dla metody @cris:

Typedef enum Nie pobierze wartości alfanumerycznych

typedef enum
{
  12Ace, 23Two, 23Three, 23Four, F22ive ... Jack, Queen, King

} CardType;

Oto kolejny:

Link Stack over flow idź do tego użytkownika odpowiedz "user1717750"

 0
Author: Puru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:39

Bazując na opublikowanym wcześniej pomyśle @ Graham Perks, zaprojektowałem prostą klasę, aby przełączanie na strunach było dość proste i czyste.

@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

Użyłbyś go tak:

[Switcher switchOnString:someString
                   using:@{
                               @"Spades":
                               ^{
                                   NSLog(@"Spades block");
                               },
                               @"Hearts":
                               ^{
                                   NSLog(@"Hearts block");
                               },
                               @"Clubs":
                               ^{
                                   NSLog(@"Clubs block");
                               },
                               @"Diamonds":
                               ^{
                                   NSLog(@"Diamonds block");
                               }
                           } withDefault:
                               ^{
                                   NSLog(@"Default block");
                               }
 ];

Poprawny blok zostanie wykonany zgodnie z łańcuchem znaków.

Gist dla tego rozwiązania

 0
Author: Chuck Krutsinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 19:04:41
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;
    }
}
Ciesz Się Kodowaniem.....
 -2
Author: Ek SAD.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 11:01:38