根据NSString值的匹配从NSMutableDictionary中删除条目

时间:2014-08-13 17:39:58

标签: ios objective-c nsstring nsmutabledictionary

在对Instagram API进行网络调用之后,我获得了一个带有以下键/值结构的responseDictionary NSDictionary委托:

{
data =     (
            {
        bio = "Los Angeles/Orange County Realtor\U00ae \n\U6d1b\U6749\U77f6\U623f\U5730\U4ea7\U7ecf\U7eaa\U4eba\nCall/Text/WhatsApp: (310) 717-1321\nEmail: Jxxxcom\nWeChat (\U5fae\U4fe1): xx";
        "full_name" = "xx yy (\U7530\U4f73\U6dfc) Rx Realty";
        id = 25354408;
        "profile_picture" = "http://scontent-a.cdninstagram.com/hphotos-xpa1/outbound-distillery/t0.0-20/OBPTH/profiles/profile_xxx_75sq_1391378894.jpg";
        username = jxxi;
        website = "http://www.Jxghty.com";
    },

profile_picture键通常包含一个NSString值,其中包含anonymousUser(对于没有设置任何个人资料图片的用户)。

我希望从responseDictionary中删除这些条目,如下所示:

        //Create mutable copy of IG responseDictionary
        NSMutableDictionary *dictCleanAvatars = [responseDictionary mutableCopy];
        NSLog(@"Log dictCleanAvatars after mutableCopy IG response: %@", dictCleanAvatars);

        NSArray *keys = [dictCleanAvatars allKeys]; //get all the keys
        NSUInteger k2 = [dictCleanAvatars count];
        NSLog(@"k2 in dictCleanAvatars before cleanup is: %lu", (unsigned long)k2);

        for (int i = 0; i<k2; i++)
        {

            if ([[dictCleanAvatars objectForKey:[keys objectAtIndex:i]] isKindOfClass:[NSString class]])
            {
                //if its an NSString - don't want an exception if its another type of object
                NSLog(@"Yes, objectAtIndex:i us Kind ofClass NSString for i = %d", i);

                if ([[dictCleanAvatars objectForKey:[keys objectAtIndex:i]] rangeOfString:@"anonymousUser"].location != NSNotFound)
                {
                    NSLog(@"Yes, anonymousUser identified in objectAtIndex:i for i = %d", i);
                    //if object has the key word im looking for
                    [dictCleanAvatars removeObjectForKey:[keys objectAtIndex:i]]; //remove the key
                    NSLog(@"That's dictCleanAvatars after loop %d: %@", i, dictCleanAvatars);
                }
            }
        }

但这不起作用。

将从更多经验丰富的iOS开发人员那里获得价值反馈。

3 个答案:

答案 0 :(得分:3)

如果您正在尝试构建一个包含data键数组中所有内容的数组,但省略profile_picture包含字符串“AnonymousUser”的字典,则可以使用{{1} }:

NSPredicate

或者您可以使用NSArray *dataArray = responseDictionary[@"data"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"not (profile_picture contains 'AnonymousUser')"]; NSArray *filteredArray = [dataArray filteredArrayUsingPredicate:predicate];

predicateWithBlock

顺便说一句,如果你已经拥有一个可变数组,你也可以使用NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSDictionary *evaluatedObject, NSDictionary *bindings) { return [evaluatedObject[@"profile_picture"] rangeOfString:@"AnonymousUser"].location == NSNotFound; }]; 使用上面的谓词从中删除条目:

filterUsingPredicate

另一方面,如果您不想从字典数组中删除整个字典,而只想删除存在“AnonymousUser”的NSMutableArray *mutableDataArray = [responseDictionary[@"data"] mutableCopy]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"not (profile_picture contains 'AnonymousUser')"]; [mutableDataArray filterUsingPredicate:predicate]; 的出现,则需要确保不仅数组是可变的,而且它的组成词典也是如此。

最简单的方法是在解析JSON时指定profile_picture选项。然后,您可以遍历NSJSONReadingMutableContainers条目,删除带有NSMutableDictionary的{​​{1}}条目,其中包含“AnonymousUser”:

profile_picture

但是,如果在解析JSON并且使用不可变集合时无法指定profile_picture选项,则需要对其进行可变复制。遗憾的是,数组的简单NSMutableDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error]; NSMutableArray *mutableDataArray = responseDictionary[@"data"]; for (NSMutableDictionary *dictionary in mutableDataArray) { NSString *profilePicture = dictionary[@"profile_picture"]; if ([profilePicture rangeOfString:@"AnonymousUser"].location != NSNotFound) { [dictionary removeObjectForKey:@"profile_picture"]; } } 不会使成员字典本身可变,但您可以使用对NSJSONReadingMutableContainers的Core Foundation调用来创建具有可变条目的可变数组,然后您可以修改:

mutableCopy

然后你可以使用上面的CFPropertyListCreateDeepCopy循环,迭代这个数组的字典条目,删除有问题的NSMutableArray *mutableDataArray = CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFArrayRef)responseDictionary[@"data"], kCFPropertyListMutableContainers)); 条目。

答案 1 :(得分:0)

if [[dictCleanAvatars objectForKey:[keys objectAtIndex:i]] isEqualToString@"anonymousUser"] {

问题是,假设[dictCleanAvatars objectForKey:[keys objectAtIndex:i]]不是NSString?您可能想先检查一下。

答案 2 :(得分:0)

如果您正在查看的唯一字段是profile_picture,那么我会使用一种更不通用的方法,这种方法更具可读性和可理解性

此代码适用于我

- (void)testExample
{
    NSDictionary *dictionary = @{ @"data": @[ @{ @"bio": @"blah blah", @"profile_picture": @"some stuff anonymousUser other stuff" },
                                              @{ @"bio": @"some other object", @"profile_picture": @"some other profile picture link" }] };
    // dictionary is a mock of the data you provided

    NSArray *data = [dictionary objectForKey:@"data"];
    for (NSDictionary * avatarDict in data) {
        NSMutableDictionary *mdict = [avatarDict mutableCopy];
        id ppid = [mdict objectForKey:@"profile_picture"];
        if ([ppid isKindOfClass:[NSString class]]) {
            NSString *pp = (NSString *)ppid;
            if ([pp rangeOfString:@"anonymousUser"].location != NSNotFound) {
                [mdict removeObjectForKey:@"profile_picture"];
            }
        }
        NSLog(@"altered dictionary: %@", mdict);
    }
}

输出:

2014-08-13 10:53:36.727 test[11981:60b] altered dictionary: {
    bio = "blah blah";
}
2014-08-13 10:53:36.728 test[11981:60b] altered dictionary: {
    bio = "some other object";
    "profile_picture" = "some other profile picture link";
}