问题
Ok, i kind of asked the wrong question so I've edited the original question.
I'm storing Arrays within Arrays, as well as NSDictionaries. It's a utility kind of application and there is no set structure, the user can enter nested information as much as they require.
Ideally I need a method to scroll through the entire contents of my array given a set parameter (a type of class, maybe a dictionary key). Here's an example..
NSMutableArray *array = [[NSMutableArray alloc]init];
NSMutableDictionary *enteredItem = [[NSMutableDictionary alloc]init];
[enteredItem setObject:@"i'm a title" forKey:@"title"];
[enteredItem setObject:@"i'm an id" forKey:@"id"];
[enteredItem setObject:@"i'm a description" forKey:@"description"];
[enteredItem setObject:@"i'm a timestamp" forKey:@"timestamp"];
[enteredItem setObject:array forKey:@"items"];
[array addObject:enteredItem];
[array addObject:anotherDictionary];
[array addObject:moreDictionaries];
So in the example above, I would need to find the dictionary (and return it) that contains @"i'm an id".
Hopefully my question is clear. Thanks for any help you can offer.
回答1:
Recursive approach is correct, but I'm not sure the code samples were very helpful if you don't already know recursion. Here's a working solution:
Add these methods:
- (id)findObjectWithKey:(id)key inArray:(NSArray *)array
{
for (id object in array)
{
if ([object isKindOfClass:[NSArray class]])
{
return [self findObjectWithKey:key inArray:object];
}
else if ([object isKindOfClass:[NSDictionary class]])
{
return [self findObjectWithKey:key inDictionary:object];
}
}
return nil;
}
- (id)findObjectWithKey:(id)key inDictionary:(NSDictionary *)dict
{
for (id subKey in dict)
{
id object = [dict objectForKey:subKey];
if ([subKey isEqual:key])
{
return object;
}
else if ([object isKindOfClass:[NSArray class]])
{
return [self findObjectWithKey:key inArray:object];
}
else if ([object isKindOfClass:[NSDictionary class]])
{
return [self findObjectWithKey:key inDictionary:object];
}
}
return nil;
}
Then to find your object, just say:
id object = [self findObjectForKey:@"title" inArray:array];
To modify the methods to find a specific object and return the dictionary key, do this instead:
- (id)findKeyWithObject:(id)key inArray:(NSArray *)array
{
for (id object in array)
{
if ([object isKindOfClass:[NSArray class]])
{
return [self findKeyWithObject:key inArray:object];
}
else if ([object isKindOfClass:[NSDictionary class]])
{
return [self findKeyWithObject:key inDictionary:object];
}
}
return nil;
}
- (id)findKeyWithObject:(id)object inDictionary:(NSDictionary *)dict
{
for (id key in dict)
{
id subObject = [dict objectForKey:key];
if ([subObject isEqual:object])
{
return key;
}
else if ([subObject isKindOfClass:[NSArray class]])
{
return [self findKeyWithObject:object inArray:object];
}
else if ([subObject isKindOfClass:[NSDictionary class]])
{
return [self findKeyWithObject:object inDictionary:object];
}
}
return nil;
}
Then to find your key, just say:
id key = [self findKeyWithObject:object inArray:array];
回答2:
How about a recursive search?
- (void) searchRecursive :(NSArray *) array {
NSEnumerator *e = [array objectEnumerator];
id obj;
while ((obj = [e nextObject])) {
if ([e isKindOfClass [NSArray class]])
[self searchRecursive :obj]
else
objobject ... forKey ...
回答3:
As ott says, a recursive approach would fit your requirements. You will also need to check if a dictionary contains the keys you want (because I guess you may have different types of objects represented by dictionaries...). Maybe you could create a NSDictionary category to check if it matches within a dictionary-class-type.
I mean:
- (void)isType1
{
return (([self objectForKey:@"title"] != nil) && [self objectForKey:@"id"] != nil) && ...);
}
I know it could be more "sophisticated" but this may be useful.
来源:https://stackoverflow.com/questions/9017197/searching-for-a-value-in-an-unknown-nsmutablearray-depth