IT

Objective-C가 NSString을 전환 할 수 있습니까?

lottoking 2020. 5. 31. 10:35
반응형

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];
} 

불행히도 그들은 할 수 없습니다. 이것은 스위치 문을 가장 잘 활용 한 것 중 하나이므로 (현재) 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"); }

애플이 몇 가지 새로운 트릭을 '전환'할 수 있기를 바랍니다.


나를 위해, 좋은 쉬운 방법 :

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;
}

불행히도 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]];

조금 늦었지만 미래의 누군가를 위해 나는 이것을 위해 나를 도울 수있었습니다.

#define CASE(str) if ([__s__ isEqualToString:(str)])
#define SWITCH(s) for (NSString *__s__ = (s); ; )
#define DEFAULT

그것을 쓰는 더 지능적인 방법이 있습니다. "맞춤법 스타일"NSNumberFormatter 에서 를 사용합니다 .

NSString *cardName = ...;

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

숫자 포맷터는 문자열을 소문자로 원하므로 포맷터로 전달하기 전에 직접해야합니다.


다른 방법이 있지만 switch그중 하나가 아닙니다.

예제와 같이 몇 개의 문자열 만 있으면 코드가 좋습니다. 많은 경우에 문자열을 사전에 키로 저장하고 해당 값을 찾을 수 있습니다.

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

NSNumber *value = [cases objectForKey:cardName];
if (value != nil) {
    [self setValue:[value intValue]];
}


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.


BY FAR.. my FAVORITE "ObjC Add-On" is 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

AND it works with non-strings, TOO... in loops, even!

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.

Best of all, there are SO few {...}'s, :'s, and ()'s


I'm kind of late to the party, but to answer the question as stated, there's a more intelligent way:

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

Note that indexOfObject will look for the match using isEqual:, exactly as in the question.


I can't Comment on cris's answer on @Cris answer but i would like to say that:

There is an LIMITATION for @cris's method:

typedef enum will not take alphanumeric values

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

} CardType;

So here is another One:

Link Stack over flow Go to this user answer "user1717750"


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


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.....

참고URL : https://stackoverflow.com/questions/8161737/can-objective-c-switch-on-nsstring

반응형