ce que l'enfer. Tant que nous relançons cette question, voici quelque chose pour l'âge de la syntaxe de la collection littérale et de l'interprétation du format visuel!
Dans le cas où quelqu'un se demande, cela fonctionne:
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]);
Résultat: "Oh Salut à James!"
Bien sûr, il y a le problème d'essayer quelque chose comme multi[3][5] = @"?"
et d'obtenir une exception d'index invalide, alors j'ai écrit une catégorie pour 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
Comme vous pouvez le voir, nous avons une méthode pratique pour faire une gamme complète de NSNull
de sorte que vous pouvez définir des indices avec l'abandon sauvage.
Deuxièmement, il existe une méthode récursive qui analyse une chaîne avec un format visuel tel que: [3][12]
(tableau 3 x 12). Si votre chaîne n'est pas valide d'une certaine façon, la méthode retournera nil
, mais si elle est valide, vous obtenez un tableau multidimensionnel complet des tailles que vous spécifiez.
Voici quelques exemples:
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
Vous pouvez passer autant de dimensions que vous le souhaitez dans la méthode de format visuel, et d'y accéder ensuite avec la syntaxe littérale, comme suit:
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]);
Quoi qu'il en soit, l'a fait plus comme un exercice que toute autre chose; c'est probablement assez efficace dans le grand schéma des choses ... en considérant comment nous fabriquons des tableaux multidimensionnels de pointeurs d'objets Objective-C.
+1 pour le type 'id' dans les tableaux C droites. – Tim
Excellente suggestion d'utiliser des tableaux C simples, en particulier lorsque les dimensions de tableau sont connues à l'avance. – timbo
+1 pour inclure à la fois la syntaxe de lecture et d'écriture. –