Это не будет наиболее эффективным, но должно работать ...
NSMutableArray* result = [[NSMutableArray alloc] init];
for (NSDictionary* dict1 in array1) {
for (NSDictionary* dict2 in array2) {
if ([[dict1 objectForKey:@"itemID"] isEqual:
[dict2 objectForKey:@"itemID"]]) {
NSMutableDictionary* dict = [dict1 mutableCopy];
[dict addEntriesFromDictionary:dict2];
[result addObject: dict];
break;
}
}
}
обновление
Вот несколько объективно-C способов повышения эффективности ...
(1) сортировать массивы перед их сравнением:
- (NSArray*)sortArray:(NSArray*)array {
NSArray* sortDescriptors =
@[[[NSSortDescriptor alloc] initWithKey:@"itemID"
ascending:YES]];
NSArray* result = [array sortedArrayUsingDescriptors:sortDescriptors];
return result;
}
(2) обратная итерация через ваши словари. Затем удаляйте конец внутреннего массива всякий раз, когда вы получаете совпадение (это разумно, учитывая, что массивы отсортированы, а удаление объектов из конца массива должно быть более эффективным, чем удаление с самого начала).
for (NSDictionary* dict1 in [sortedArray1 reverseObjectEnumerator]) {
for (NSDictionary* dict2 in [sortedArray2 reverseObjectEnumerator]) {
if ([[dict1 objectForKey:@"itemID"] isEqual:
[dict2 objectForKey:@"itemID"]]) {
NSMutableDictionary* dict = [dict1 mutableCopy];
[dict addEntriesFromDictionary:dict2];
[result addObject: dict];
NSUInteger idx = [sortedArray2 indexOfObject:dict2];
NSRange range= NSMakeRange(idx, sortedArray2.count-1-idx);
[sortedArray2 removeObjectsInRange:range];
break;
}
}
}
(3) использовать блок на основе быстрого перечисления:
[sortedArray1 enumerateObjectsWithOptions:NSEnumerationReverse
usingBlock:
^(NSDictionary* dict1, NSUInteger idx, BOOL *stop) {
[sortedArray2 enumerateObjectsWithOptions:NSEnumerationReverse
usingBlock:
^(NSDictionary* dict2, NSUInteger jdx, BOOL *stop) {
if ([[dict1 objectForKey:@"itemID"] isEqual:
[dict2 objectForKey:@"itemID"]]) {
NSMutableDictionary* dict = [dict1 mutableCopy];
[dict addEntriesFromDictionary:dict2];
[result addObject: dict];
NSRange range= NSMakeRange(jdx, sortedArray2.count-1-jdx);
[sortedArray2 removeObjectsInRange:range];
*stop = YES;
}
}];
}];
Там может быть незначительным вычислительная разница между (2) и (3), но (3) имеет преимущество Передает индекс и объект на каждой итерации, тогда как в (2) вам нужно получить индекс, используя indexOfObject
.
Если вы уверены, что каждый массив имеет один и тот же набор значений ключей сравнения, вы можете обойтись без NSRange
и упростить внутреннее сокращение массива в:
[sortedArray2 removeLastObject];
наконец ...
Если по вашему вопросу вы заранее знаете, что ваши данные отсортированы и что между соответствующими объектами массива существует взаимно однозначное соответствие, вы можете упростить:
[arrayA enumerateObjectsUsingBlock:
^(NSDictionary* dict, NSUInteger idx, BOOL *stop) {
NSMutableDictionary* mutableDict = [dict mutableCopy];
[mutableDict addEntriesFromDictionary:arrayB[idx]];
[result addObject:mutableDict];
}];
Большое спасибо за очень информативный и пошаговый ответ! Извините, я получаю сообщение об ошибке «Ожидаемое выражение», когда я пытаюсь использовать последний параметр. Ошибка находится в строке [arrayA enumerateObjectsUsingBlock: { Есть ли ошибка в синтаксисе? – user2716667
@ user2716667 - да, было несколько ошибок ... посторонний '{' on line 1 и отсутствующий '' 'в строке 4. Исправлено. – foundry
Вы правы, два массива имеют точно такое же количество элементов. – user2716667