1

编辑:更好的例子......

所以我有一个“现有”对象的 NSMutableSet,我想下载 JSON 数据,解析它,并将这些新对象与我现有的对象合并,用新下载的对象更新任何重复的对象。以下是现有对象集的样子:


NSArray *savedObjects = [NSArray arrayWithObjects:
    [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"id", @"hello there", @"body", @"200", @"score", nil],
    [NSDictionary dictionaryWithObjectsAndKeys:@"2", @"id", @"hey now", @"body", @"10", @"score", nil],
    [NSDictionary dictionaryWithObjectsAndKeys:@"3", @"id", @"welcome!", @"body", @"123", @"score", nil],
    nil
];
self.objects = [NSMutableSet setWithArray:savedObjects];

// after downloading and parsing JSON... I have an example array of objects like this:

NSArray *newObjects = [NSArray arrayWithObjects:
    [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"id", @"hello there", @"body", @"9999", @"score", nil],
    [NSDictionary dictionaryWithObjectsAndKeys:@"4", @"id", @"what's new", @"body", @"22", @"score", nil],
    nil
];

因此,例如,在合并这个新对象后,id 为 1 的对象现在的得分为 9999,并且一个新的 id 为 4 的对象将被添加到集合中。

我真的想避免为每个新对象循环遍历 NSMutableSet 只是为了检查 @"id" 属性是否存在......我在想我可以使用 addObjectsFromArray 来合并这些新对象,但看起来因为属性不同(例如:得分:9999)它没有将新对象视为集合中的现有对象。

我使用数字作为字符串来简化这个例子。我还想避免使用仅限 iOS SDK 4.0 的功能,因为该应用程序将与 3.0 兼容。

万分感谢!我很感激!

4

3 回答 3

4

从你的问题中不能完全确定(因为它是一个 iphone 问题,所以应该使用客观的 c 表示法),但听起来 NSDictionary 可能是你最好的朋友。

于 2010-10-28T18:23:47.037 回答
0
NSArray *array = ... // contains the new dictionary objects.
NSMutableSet *set = ... // contains the existing set of dictionary objects. 

for (id arrayItem in array)
{
    id setItem = [[set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"id.intValue = %d", [[arrayItem valueForKey:@"id"] intValue]]] anyObject];
    if (setItem != nil)
    {
        [set removeObject:setItem];
        [set addObject:arrayItem];
    }
}
于 2010-10-28T19:13:19.560 回答
0

最好的办法是使用 @"id" 参数将第一组转换为字典。下面是一些应该做你想做的事情的代码,它甚至可以处理没有 @"id" 参数的字典的情况(此时它们不会被合并,只是包含在结果中):

// here is the NSSet you already have
self.objects = [NSSet setWithObjects:
    [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"id", @"hello there", @"body", @"200", @"score", nil],
    [NSDictionary dictionaryWithObjectsAndKeys:@"2", @"id", @"hey now", @"body", @"10", @"score", nil],
    [NSDictionary dictionaryWithObjectsAndKeys:@"3", @"id", @"welcome!", @"body", @"123", @"score", nil],
    nil];

// after downloading and parsing JSON... I have an example array of objects like this:

NSArray *newObjects = [NSArray arrayWithObjects:
    [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"id", @"hello there", @"body", @"9999", @"score", nil],
    [NSDictionary dictionaryWithObjectsAndKeys:@"4", @"id", @"what's new", @"body", @"22", @"score", nil],
    nil];

// Convert self.objects into a dictionary for merging purposes
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:[self.objects count]];
NSMutableSet *remainder = [NSMutableSet set]; // for objects with no @"id"
for (NSDictionary *obj in self.objects) {
    NSString *objId = [obj objectForKey:@"id"];
    if (objId) {
        [dict setObject:obj forKey:objId];
    } else {
        [remainder addObject:obj];
    }
}

// merge the new objects in
for (NSDictionary *obj in newObjects) {
    NSString *objId = [obj objectForKey:@"id"];
    if (objId) {
        // merge the new dict with the old
        // if you don't want to merge the dict and just replace,
        // simply comment out the next few lines
        NSDictionary *oldObj = [dict objectForKey:objId];
        if (oldObj) {
            NSMutableDictionary *newObj = [NSMutableDictionary dictionaryWithDictionary:oldObj];
            [newObj addEntriesFromDictionary:obj];
            obj = newObj;
        }
        // stop commenting here if you don't want the merging
        [dict setObject:newObj forKey:objId];
    } else {
        [remainder addObject:obj];
    }
}

// add the merged dicts back to the set
[remainder addObjectsFromArray:[dict allValues]];
self.objects = remainder;
于 2010-10-28T22:49:27.867 回答