এনএসএসস্ট্রিং-এর উদ্দেশ্য-সি স্যুইচ করা যাবে কি?


166

এটি আবার লেখার আরও বুদ্ধিমান উপায় আছে কি?

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
না, স্যুইচ কেবলমাত্র ইন / বিল / চর / ইত্যাদি প্রকারে কাজ করে।
chown

এই প্রশ্নটি কিছুটা হলেও এক ঘন্টা আগে পোস্ট করা হয়েছে (
স্ট্যাকওভারফ্লো / সেকশনস / 8161319/…

3
এটি করার বিভিন্ন বিকল্প উপায় রয়েছে। উদাহরণস্বরূপ, মানগুলির সাথে একটি অ্যারে লোড করুন এবং অ্যারেতে একটি মিল অনুসন্ধান করুন। কোনওটিই মারাত্মকভাবে দক্ষ নয়, তবে তারা কোডের নকলকে হ্রাস করে।
হট লিক্স

4
পার্শ্ব নোট হিসাবে, অ্যাপলের নতুন ভাষা (সুইফট) এখন একটি সুইচ বিবৃতিতে স্ট্রিংগুলির তুলনা করার অনুমতি দেয়!
জ্যারেডস্মিথ

উত্তর:


147

দুর্ভাগ্যক্রমে তারা পারে না। এটি স্যুইচ স্টেটমেন্টগুলির সদ্ব্যবহারের অন্যতম সেরা এবং সর্বাধিক সন্ধানকারী, তাই আশা করি তারা (এখন) জাভা (এবং অন্যদের) ব্যান্ডওয়্যাগনে হ্যাপ করবেন!

আপনি যদি কার্ডের নাম করে থাকেন তবে সম্ভবত প্রতিটি কার্ডের জন্য একটি পূর্ণসংখ্যার মান নির্ধারণ করুন এবং এটি স্যুইচ করুন। অথবা সম্ভবত একটি এনাম, যা একটি সংখ্যা হিসাবে বিবেচিত হয় এবং তাই এটি চালু করা যেতে পারে।

যেমন

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

} CardType;

এইভাবে সম্পন্ন হলে, এসের কেস 0, দুটি কেস 1 হিসাবে সমান হবে Two


4
@ আব্বুড এনাম সম্পর্কে আরও তথ্যের জন্য, ম্যাট থম্পসন দ্বারা পোস্ট করা এনএস_ইএনএম এবং এনএস_অপশন দেখুন
তুলসী বাউরক

@ আবদুব আপনার মন্তব্য মানে কি? এর মতো মনে হচ্ছে এটি খারাপ উত্তর তবে আমার কাছে ঠিক আছে। আপনি ব্যাখ্যা করতে পারেন?
অ্যালান অ্যান্ড্রেড

আমি যেমন বুঝতে পেরেছি, CardTypeকোনও সংযুক্ত @""[CardType isEqualToString:@"Three"]
উদাহরণের

120

আপনি এই জাতীয় ব্লকগুলির অভিধান তৈরি করতে পারেন:

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

আশা করি অ্যাপল কয়েকটি নতুন কৌশল 'সুইচ' শিখিয়ে দেবে।


35
আমি বলতে পারি না এটি সত্যিই বাজে বা সত্যিই দুর্দান্ত। ধন্যবাদ, কখনও এই কাজ করার কথা ভাবিনি।
endy

2
আমরা যখন এইরকম অদ্ভুত জিনিস করছি, তখন কেন আপনার নিজের শ্রেণি তৈরি করবেন না যা কোনও ব্লক অবজেক্টের জন্য এনএসডিআরঙের কী দ্বারা পূর্ণ এনএসডি অভিধানকে আবৃত করে এবং তারপরে ডিফল্ট মামলার জন্য অন্য একটি ব্লক সরবরাহ করে? এমনকি আপনি এটি সাবস্ক্রিপ্ট স্বরলিপি সমর্থন করতে পারেন।
আর্টঅফ ওয়ারফেয়ার

1
আপনি যদি কেবলমাত্র এর জন্য এনএসডেটরিয় সাবক্লাস তৈরি করেন তবে অতিরিক্ত পয়েন্টগুলি: পি
কমাটোস্ট

2
হুডের নীচে, বৃহত্তর স্যুইচ স্টেটমেন্টগুলির জন্য এটি সি # এভাবে করে।
হ্যাঙ্ক শুল্টজ

78

আমার জন্য, একটি দুর্দান্ত সহজ উপায়:

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

1
আমি এই পছন্দ। এটি এই সমস্যার উত্তর খুঁজতে সর্বাধিক প্রয়োজনের জবাব দেয়, জাভাস্ক্রিপ্টে অনুরূপ সুইচ নেওয়ার চেয়ে বেশি টাইপিং লাগে না এবং এটি মানব পাঠযোগ্য।
প্যারিস

4
আমি এই হ্যাকটিকে জেএস সুইচের সাথে তুলনা করব না। পরবর্তী প্রোগ্রামার আইটেম 1 এবং আইটেম 2 এর মধ্যে একটি আইটেম যুক্ত করলে কী হবে? বাগ প্রবর্তনের জন্য খুব বেশি সম্ভাবনা
আরস

যদিও এটি একটি দুর্দান্ত হ্যাক, তাই আমি আপনাকে প্রচেষ্টাটির জন্য থাম্বস দিচ্ছি :)
আরাস

@ আরস যদি পরবর্তী প্রোগ্রামারকে নতুন এন্ট্রি যুক্ত করতে হয় তবে তারা এটি পরিচালনা করতে অ্যারের শেষে একটি নতুন কেস স্টেটমেন্ট যুক্ত করবে। সুতরাং অ্যারেতে "" আইটেম 3 "এর পরে @" আইটেম 0 "যুক্ত করা যায়, তারপরে এটি পরিচালনা করতে একটি কেস 3 যোগ করুন।
sbonkosky

1
আমি আপনার উপায় সম্পূর্ণ পছন্দ। এটা খুব ঝরঝরে। আমি বিভাগটি লিখছি এবং আমার সাথে স্ট্রিং থাকাকালীন ইউআইসিওলর ফিরে আসতে হবে।
অ্যালিক্স

11

দুর্ভাগ্যক্রমে, স্যুইচ স্টেটমেন্টগুলি কেবল আদিম ধরণের ক্ষেত্রে ব্যবহার করা যেতে পারে। যদিও আপনার কাছে সংগ্রহগুলি ব্যবহার করে কয়েকটি বিকল্প রয়েছে।

সম্ভবত সেরা বিকল্পটি হ'ল এনএসডি অভিধানে প্রতিটি মান একটি প্রবেশিকা হিসাবে সংরক্ষণ করা।

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

8

কিছুটা দেরি হলেও ভবিষ্যতে যে কারও জন্য আমি এটি আমার পক্ষে কাজ করতে সক্ষম হয়েছি

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

এটা মজার. আপনি আরও বিস্তারিত বলতে পারেন?
চেন লি ইয়ং

6

এটি লেখার আরও বুদ্ধিমান উপায় এখানে। এটি একটি ব্যবহার করবেন তা NSNumberFormatter"বানান-আউট শৈলী" :

NSString *cardName = ...;

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

নোট করুন যে সংখ্যার ফর্ম্যাটারটি স্ট্রিংটি নিম্নতর করতে চায়, সুতরাং এটি ফর্ম্যাটারে দেওয়ার আগে আমাদের তা করতে হবে।


5

এটি করার অন্যান্য উপায় আছে তবে সেগুলির মধ্যে switchএকটিও নয়।

আপনার উদাহরণ হিসাবে যেমন কয়েকটি স্ট্রিং থাকে তবে আপনার কোডটি ঠিক আছে। আপনার যদি অনেকগুলি মামলা থাকে তবে আপনি অভিধানে কী হিসাবে স্ট্রিংগুলি সঞ্চয় করতে পারেন এবং সংশ্লিষ্ট মানটি সন্ধান করতে পারেন:

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

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

4

খুব দূরে .. আমার পছন্দের "ওবিজেসি অ্যাড-অন" isObjectMatcher

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

এবং এটি লুপগুলিতে এমনকি অ-স্ট্রিংগুলির সাথেও কাজ করে!

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.

সর্বোপরি, এখানে কয়েকটি {...}'গুলি :' এবং ()'এস' রয়েছে


3

অবজেক্টিভ-সি এই দিক থেকে গ থেকে আলাদা নয়, এটি কেবল সি কী করতে পারে তা পরিবর্তন করতে পারে (এবং প্রিপ্রোক ডিএফ এর মতো এনএসআইন্টিজার, এনএসইআইএনটিজার, যেহেতু তারা শেষ পর্যন্ত কেবল একটি ইন্টিগ্রাল টাইপের টাইপডেফ হয়)।

উইকিপিডিয়া:

সি বাক্য গঠন :

স্যুইচ স্টেটমেন্টটি নিয়ন্ত্রণের কারণ হিসাবে প্রকাশের মানের উপর নির্ভর করে কয়েকটি বিবৃতিগুলির একটিতে স্থানান্তরিত করে, যার অবশ্যই অবিচ্ছেদ্য প্রকার থাকতে হবে

ইন্টিগ্রাল প্রকার :

কম্পিউটার বিজ্ঞানে, একটি পূর্ণসংখ্যা হল ইন্টিগ্রাল ডেটা টাইপের একটি ডেটাম, এমন একটি ডেটা টাইপ যা গাণিতিক পূর্ণসংখ্যার কিছু সীমাবদ্ধ উপসেট উপস্থাপন করে। ইন্টিগ্রাল ডেটা ধরণের বিভিন্ন আকারের হতে পারে এবং নেতিবাচক মান থাকতে পারে বা নাও হতে পারে।


2

আমি পার্টিতে একদম দেরি করছি, তবে যেমনটি বলা হয়েছে সেই প্রশ্নের উত্তর দিতে আরও বুদ্ধিমান উপায় আছে:

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

নোট যেটি indexOfObjectম্যাচের জন্য ব্যবহার করবে isEqual:ঠিক যেমন প্রশ্নের মধ্যে রয়েছে Note


2

এর আগে পোস্ট করা গ্রাহাম পার্কস আইডিয়ায় বিল্ডিং, স্ট্রিংগুলিকে সাদামাটা সহজ এবং পরিষ্কার করার জন্য একটি সাধারণ ক্লাস ডিজাইন করেছে।

@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");
                               }
 ];

সঠিক ব্লকটি স্ট্রিং অনুযায়ী কার্যকর করা হবে।

এই সমাধানের জন্য সংক্ষেপে


0

আমি ক্রিসের উত্তর সম্পর্কে ক্রিসের উত্তর সম্পর্কে মন্তব্য করতে পারি না তবে আমি এটি বলতে চাই:

@ ক্রিসের পদ্ধতির জন্য একটি সীমাবদ্ধতা রয়েছে:

টাইপডেফ এনাম বর্ণানুক্রমিক মান গ্রহণ করবে না

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

} CardType;

সুতরাং এখানে অন্য এক:

প্রবাহের ওপরে লিঙ্ক স্ট্যাক এই ব্যবহারকারীর উত্তর "ইউজার 1717750" এ যান


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

কোডিং উপভোগ করুন .....

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.