Finding Value in Unknown Depth NSMutableArray

Ok, I asked the wrong question, so I edited the original question.

I store arrays in arrays as well as NSDictionaries. This is a useful type of application and there is no established structure; the user can enter the embedded information as much as required.

Ideally, I need a method to scroll through the entire contents of my array with a given parameter (class type, possibly a dictionary key). Here is 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 above example, I will need to find the dictionary (and return it) containing @ "i is id".

Hope my question is clear. Thanks for any help you can offer.

+4
source share
3 answers

The recursive approach is correct, but I'm not sure if the code samples were very useful if you don't already know the recursion. Here's a working solution:

Add the following 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 change the search methods of 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]; 
+4
source

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 ... 
+1
source

As ott says, a recursive approach will fit your requirements. You will also need to check if the dictionary contains the keys you need (because, I think, you can have different types of objects represented by dictionaries ...). Perhaps you could create an NSDictionary category to check if it matches the type of the dictionary class.

I mean:

 - (void)isType1 { return (([self objectForKey:@"title"] != nil) && [self objectForKey:@"id"] != nil) && ...); } 

I know that this can be more "complicated", but it can be useful.

+1
source

Source: https://habr.com/ru/post/1393141/


All Articles