Searching for a value in an unknown NSMutableArray depth

删除回忆录丶 提交于 2019-12-12 09:42:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!