2D arrays using NSMutableArray

后端 未结 8 832
夕颜
夕颜 2020-11-29 21:41

I need to create a mutable two-dimensional array in Objective-C.

For example I have:

NSMutableArray *sections;
NSMutableArray *rows;
<
8条回答
  •  一整个雨季
    2020-11-29 22:08

    what the hell. As long as we're reviving this question, here's something for the age of literal collection syntax and visual format interpretation!

    In case anyone is wondering, this works:

    NSMutableArray *multi = [@[ [@[] mutableCopy] , [@[] mutableCopy] ] mutableCopy];
    multi[1][0] = @"Hi ";
    multi[1][1] = @"There ";
    multi[0][0] = @"Oh ";
    multi[0][1] = @"James!";        
    NSLog(@"%@%@%@%@", multi[0][0], multi[1][0], multi[1][1], multi[0][1]);
    

    Result: "Oh Hi There James!"

    Of course, there is the problem of trying something like multi[3][5] = @"?" and getting an invalid index exception, so I wrote a category for NSMutableArray.

    @interface NSMutableArray (NullInit)
    +(NSMutableArray *)mutableNullArrayWithSize:(NSUInteger)size;
    +(NSMutableArray *)mutableNullArraysWithVisualFormat:(NSString *)string;
    @end
    
    @implementation NSMutableArray (NullInit)
    
    +(NSMutableArray *)mutableNullArrayWithSize:(NSUInteger)size
    {
        NSMutableArray *returnArray = [[NSMutableArray alloc] initWithCapacity:size];
        for (int i = 0; i < size; i++) {
            [returnArray addObject:[NSNull null]];
        }
        return returnArray;
    }
    
    +(NSMutableArray *)mutableNullArraysWithVisualFormat:(NSString *)string
    {
        NSMutableArray *returnArray = nil;
        NSRange bitRange;
        if ((bitRange = [string rangeOfString:@"^\\[\\d+]" options:NSRegularExpressionSearch]).location != NSNotFound) {
            NSUInteger size = [[string substringWithRange:NSMakeRange(1, bitRange.length - 2)] integerValue];
            if (string.length == bitRange.length) {
                returnArray = [self mutableNullArrayWithSize:size];
            } else {
                returnArray = [[NSMutableArray alloc] initWithCapacity:size];
                NSString *nextLevel = [string substringWithRange:NSMakeRange(bitRange.length, string.length - bitRange.length)];
                NSMutableArray *subArray;
                for (int i = 0; i < size; i++) {
                    subArray = [self mutableNullArraysWithVisualFormat:nextLevel];
                    if (subArray) {
                        [returnArray addObject:subArray];
                    } else {
                        return nil;
                    }
                }
            }
        } else {
            return nil;
        }
        return returnArray;
    }
    
    @end
    

    As you can see, we have a convenience method for making an array full of NSNull so that you can set indices with wild abandon.

    Secondly, there's a recursive method that parses a string with a visual format like: [3][12] (3 x 12 array). If your string is invalid in some way the method will return nil, but if it's valid you get a whole multidimensional array of the sizes you specify.

    Here are some examples:

    NSMutableArray *shrub = [NSMutableArray mutableNullArrayWithSize:5];
    NSMutableArray *tree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[3][12]"]; // 2-Dimensional Array
    NSMutableArray *threeDeeTree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[3][5][6]"]; // 3-Dimensional Array
    NSMutableArray *stuntedTree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[6][4][k]"]; // Returns nil
    

    You can pass as many dimensions as you like into the visual format method, and then access them with the literal syntax, like so:

    NSMutableArray *deepTree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[5][3][4][2][7]"];
    deepTree[3][2][1][0][5] = @"Leaf";
    NSLog(@"Look what's at 3.2.1.0.5: %@", deepTree[3][2][1][0][5]);
    

    Anyway, did this more as an exercise than anything else; it's probably pretty efficient in the grand scheme of things...considering as how we're making multi-dimensional arrays of Objective-C object pointers.

提交回复
热议问题