3
// Values of the individual days as powers of two
enum {
    kMonday = 64,
    kTuesday = 32,
    kWednesday = 16,
    kThursday = 8,
    kFriday = 4,
    kSaturday = 2,
    kSunday = 1,
};

127 種類の曜日すべてを人間が読める文字列に変換する最速の方法は何ですか?

たとえば、7 という数字を取得した場合、「Fri-Sunday」を出力したいと思います。

66 という数字を取得した場合、「月、土曜日」を出力したいと思います。

4

2 に答える 2

3

基本的に、次の 2 つのオプションがあります。

  • Factory を作成します。結合された日数の整数を渡すと、文字列が返されます

  • int をラップし、内部のロジックにアクセスするメソッドを提供するラッパー オブジェクトを作成します。

私はラッパーを書きました:

#import <Foundation/Foundation.h>

typedef NS_OPTIONS(NSUInteger, WeekDays) {
    kMonday     = 1 << 6,
    kTuesday    = 1 << 5,
    kWednesday  = 1 << 4,
    kThursday   = 1 << 3,
    kFriday     = 1 << 2,
    kSaturday   = 1 << 1,
    kSunday     = 1 << 0
};

@interface DaysWrapper : NSObject
-(id)initWithDays:(WeekDays)weekDays;
@end

@interface DaysWrapper ()
@property (nonatomic,retain) NSMutableArray *days;
@end


@implementation DaysWrapper{
    int internalDays;
}

+(instancetype)dayWrapperWithDayBitmask:(WeekDays)daybits
{
    return [[DaysWrapper alloc] initWithDays:daybits];
}

-(instancetype)initWithDays:(WeekDays)weekDays
{
    if (self = [super init]) {
        WeekDays wholeWeek = 127;
        internalDays = weekDays & wholeWeek;
        _days = [@[] mutableCopy];

        while (wholeWeek) {
            wholeWeek >>= 1;
            if (weekDays & (wholeWeek +1)) {
                [_days addObject:[NSNumber numberWithBool:YES]];
            } else {
                [_days addObject:[NSNumber numberWithBool:NO]];
            }
        }
    }
    return self;
}

-(NSString *)description
{
    static dispatch_once_t onceToken;
    static NSArray *dayNames;
    static NSDictionary *fullnamesForDayNames;
    dispatch_once(&onceToken, ^{
        dayNames = @[@"Mon", @"Tues", @"Wend",@"Thu", @"Fri",@"Sat", @"Sun"];
        fullnamesForDayNames = [[NSDictionary alloc] initWithObjects: @[@"Monday",@"Tuesday",@"Wendsday",@"Thursday",@"Friday",@"Saturday",@"Sunday"]
                                                             forKeys:dayNames];
    });


    NSMutableString *returnSting = [@"" mutableCopy];
    __block BOOL previousWasAvailable = NO;
    NSMutableArray *dayRanges = [@[] mutableCopy];
    [self.days enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (!previousWasAvailable && [obj boolValue])
            [dayRanges addObject:[@[] mutableCopy]];

        if ([obj boolValue]) {
            NSMutableArray *actualRange = [dayRanges lastObject];
            [actualRange addObject:dayNames[idx]];
        }
        previousWasAvailable = [obj boolValue];
    }];

    [dayRanges enumerateObjectsUsingBlock:^(NSMutableArray *rangeArray, NSUInteger idx, BOOL *stop) {

        if ([returnSting length]){
            [returnSting appendString:@","];
        }

        if ([rangeArray count] > 1) {
            [returnSting appendString: [rangeArray firstObject]];

            if ([rangeArray count] > 2){
                [returnSting appendString:@"-"];
            } else {
                [returnSting appendString:@","];
            }
        }

        if (idx == [dayRanges count]-1){
            [returnSting appendString: fullnamesForDayNames[[rangeArray lastObject]]];
        } else {
            [returnSting appendString:[rangeArray lastObject]];
        }
    }];

    return returnSting;
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {

        WeekDays monAndFriday    = kMonday | kFriday;
        WeekDays thurToSat       = kThursday | kFriday | kSaturday;
        WeekDays weekEnd         = kFriday | kSaturday | kSunday;
        WeekDays mondAndWeekend  = weekEnd | kMonday;
        WeekDays friSat          = kFriday | kSaturday;
        WeekDays everySecondDay  = 8 | 32 | 2;
        WeekDays moday           = kMonday;
        WeekDays workWeek        = kMonday | kTuesday | kWednesday | kThursday | kFriday;
        WeekDays wholeWeek       = workWeek | weekEnd;
        WeekDays notThursday     =  ~kThursday & wholeWeek;

        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:monAndFriday]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:weekEnd]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:thurToSat]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:mondAndWeekend]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:friSat]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:everySecondDay]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:moday]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:workWeek]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:wholeWeek]);
        NSLog(@"%@", [DaysWrapper dayWrapperWithDayBitmask:notThursday]);
    }
    return 0;
}

出力

Mon,Friday
Fri-Sunday
Thu-Saturday
Mon,Fri-Sunday
Fri,Saturday
Tues,Thu,Saturday
Monday
Mon-Friday
Mon-Sunday
Mon-Wend,Fri-Sunday

ランダムな考え

  • 整数の情報のコピーを配列 name に保持する代わりに、self.daysスペースを削減するために必要になるたびにその場で処理できます
  • 工場は基本的に同じロジックを持っています

一般的なコードのオーバーホール (ARC、最新の obj-c 構文、NS_OPTIONS など) 2015 年 5 月 21 日

于 2012-05-29T18:51:39.353 に答える
3

これは面白い挑戦でした。

#import <Foundation/Foundation.h>
enum {
    kMonday = 1 << 0,
    kTuesday = 1 << 1,
    kWednesday = 1 << 2,
    kThursday = 1 << 3,
    kFriday = 1 << 4,
    kSaturday = 1 << 5,
    kSunday = 1 << 6,
};
typedef int DayBits;

NSString * const shortDayNames[] = { @"Mon", @"Tues", @"Wed", @"Thurs", @"Fri", @"Sat", @"Sun" };
NSString * const fullDayNames[] = { @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday", @"Sunday" };


int main(int argc, const char * argv[])
{

    @autoreleasepool {
        // Demo all possible combinations
        for( DayBits days_as_bits = 0; days_as_bits < 128; days_as_bits++ ){
            // Create an index set from the bits
            NSMutableIndexSet * indexes = [NSMutableIndexSet indexSet];
            for( int bit = 0; bit < 7; bit++ ){
                if( days_as_bits & (1 << bit) ){
                    [indexes addIndex:bit];
                }
            }

            // Create string for result
            NSMutableString * daysDesc = [NSMutableString string];
            // Enumerate the index set backwards and build up the string
            __block BOOL contiguous = NO;
            [indexes enumerateIndexesWithOptions:NSEnumerationReverse 
                                      usingBlock:^(NSUInteger idx, BOOL *stop) {
                // Use short names unless this is the name that will appear 
                // at the end of the string
                NSString * const * dayNames = shortDayNames;
                if (0 == [daysDesc length]) {
                    dayNames = fullDayNames;
                }
                // If the previous index is present, we're working on a contiguous set
                if( [indexes containsIndex:(idx - 1)] ){
                    // If we were already in a contiguous set, just continue
                    if( contiguous ){
                        return;
                    }
                    // This is the end day of a contiguous set; place the name 
                    // and a hyphen
                    else {
                        [daysDesc insertString:[NSString stringWithFormat:@"-%@", dayNames[idx]]
                                                                  atIndex:0];
                        contiguous = YES;
                        return;
                    }
                }
                // We've reached the start day of a set. 
                // Turn off contiguous and fall through
                else {
                    contiguous = NO;
                }

                // Place a comma and today's name
                [daysDesc insertString:[NSString stringWithFormat:@", %@", dayNames[idx]]
                                                          atIndex:0];
            }];
            // Clean up extraneous comma and space at the beginning of the string
            daysDesc = [daysDesc stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ,"]];
            NSLog(@"%d: %@", days_as_bits, daysDesc);
        }

    }
    return 0;
}

enum私はそれを機能させるためにあなたの周りを切り替えたことに注意してください. これは、たとえば、7 がkMonday | kTuesday | kWednesdayではなくkFriday | kSaturday | kSunday、結果が であることを意味しMon-Wedます。

インデックス セットの使用は、おそらく私が提供しなければならない主な洞察だと思います。

いくつかの作業で物事を元に戻すことができる場合があります(とりわけ、列挙を元に戻すなど)。私は十分に時間を無駄にしました^W^W^Wこれで私の好奇心を満たす.

于 2012-05-29T22:57:49.470 に答える