объединить nsarray в nsset и избежать дубликатов в target-c на iphone - PullRequest
1 голос
/ 28 октября 2010

Редактировать: лучший пример ...

Итак, у меня есть 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
];

Так, например, после объединения этого нового объекта объект с идентификатором 1 теперь будет иметь оценку 9999, а новый объект с идентификатором 4 будетдобавлен в набор.

Я действительно хочу избежать циклического перебора NSMutableSet для каждого нового объекта, просто чтобы убедиться, что свойство @ "id" существует ... Я думал, что мог бы использовать addObjectsFromArray для объединения этих новых объектовно похоже, поскольку свойства различаются (например, счет: 9999), новые объекты не рассматриваются как существующие объекты в наборе.

Я использую числа в качестве строк, чтобы упростить этот пример.Я также хотел бы избегать использования функций iOS SDK 4.0, поскольку приложение будет совместимо с 3.0.

Спасибо огромное!Я ценю это!

Ответы [ 3 ]

4 голосов
/ 28 октября 2010

Не совсем уверен в вашем вопросе (так как это вопрос iphone, должна использоваться целевая нотация c), но, похоже, NSDictionary мог бы быть вашим лучшим другом.

0 голосов
/ 29 октября 2010

Лучше всего конвертировать первый набор в словарь с помощью параметра @ "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;
0 голосов
/ 28 октября 2010
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];
    }
}
...