что ад. Пока мы возобновляем этот вопрос, вот что-то для возраста литерального синтаксиса коллекции и интерпретации визуального формата!
В случае, если кто-то интересно, это работает:
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]);
Результат: "О Привет Там Джеймс!"
Конечно, есть проблема попробовать что-то вроде multi[3][5] = @"?"
и получить недопустимое исключение индекса, поэтому я написал категорию для 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
Как вы можете видеть, у нас есть удобный метод для создания массива полного NSNull
, так что вы можете установить индексы с разнузданностью.
Во-вторых, существует рекурсивный метод, который анализирует строку с визуальным форматом, например: [3][12]
(массив 3 x 12). Если ваша строка некорректна, метод возвращает nil
, но если он действителен, вы получаете целый многомерный массив указанных вами размеров.
Вот некоторые примеры:
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
Вы можете пройти столько размеры, как вам нравится в визуальный метод форматирования, а затем получить доступ к ним с буквальным синтаксиса, например, так:
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]);
Во всяком случае, это было больше упражнением, чем чем-либо еще; это, вероятно, довольно эффективно в великой схеме вещей ... учитывая, как мы создаем многомерные массивы объектных указателей Objective-C.
+1 для 'id' типа в прямых массивов C. – Tim
Отличное предложение использовать простые массивы C, особенно когда размеры массива известны заранее. – timbo
+1 для включения синтаксиса чтения и записи. –