Лучшее решение для этого быстрого двукратного перечисления? - PullRequest
1 голос
/ 26 сентября 2011

Я перебираю массив и сравниваю свойство тега objects в этом массиве с объектами в другом массиве.

Вот мой код:

NSArray *objectsArray = ...;
NSArray *anotherObjectArray = ...;
NSMutableArray *mutableArray = ...;

for (ObjectA *objectA in objectsArray) {
    for (ObjectZ *objectZ in anotherObjectArray) {
        if ([objectA.tag isEqualToString:objectZ.tag]) {
            [mutableArray addObject:objectA];
        }
    }
}

Есть ли лучший способ сделать это?

Обратите внимание, что свойство tag не является целым числом, поэтому необходимо сравнить строки.

Ответы [ 4 ]

5 голосов
/ 26 сентября 2011

Это можно сделать, выполнив итерацию по каждому массиву один раз, а не вложив:

NSMutableSet *tagSet = [NSMutableSet setWithCapacity:[anotherObjectArray count]];

for(ObjectZ *objectZ in antherObjectArray) {
    [tagSet addObject:objectZ.tag];
}

NSMutableArray *output = [NSMutableArray mutableArray];

for(ObjectA *objectA in objectsArray) {
    if([tagSet containsObject:objectA.tag]) {
        [output addObject:objectA];
    }
}
1 голос
/ 26 сентября 2011

Может быть, вы можете использовать [NSArray FilterArrayUsingPredicate:]; - http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html

Но вам, возможно, придется настроить тег свойства самостоятельно.

NSArray *objectsArray = [NSArray arrayWithObjects:@"Miguel", @"Ben", @"Adam", @"Melissa", nil];
NSArray *tagsArray = [NSArray arrayWithObjects:@"Miguel", @"Adam", nil];

NSPredicate *sPredicate = [NSPredicate predicateWithFormat:@"SELF IN %@", tagsArray];
NSArray *results = [objectsArray filteredArrayUsingPredicate:sPredicate];
NSLog(@"Matched %d", [results count]);
for (id a in results) {
    NSLog(@"Object is %@", a);
}

Надеюсь, это поможет

1 голос
/ 26 сентября 2011

Что ж, самое простое изменение (поскольку может быть только одно совпадение для объекта A), тогда вы можете сделать разрыв после [mutableArray addObject: objectA].Когда совпадение происходит, это приведет к сокращению внутреннего цикла на 50%.

Еще более драматично, если вы делаете это много, и порядок anotherObjectArray не имеет значения, будет инвертировать структуру данных anotherObjectArray.и использовать словарь, сохраняя объекты по тегу.Затем вы просто перебираете objectA, спрашивая, есть ли его тег в словаре ObjectZ.

0 голосов
/ 27 сентября 2011

Спасибо за все ответы. В то время как я принял решение NSMutableSet, я на самом деле закончил со следующим: оказалось, что это было немного быстрее:

NSMutableDictionary *tagDictionary = [NSMutableDictionary dictionaryWithCapacity:[anotherObjectArray count]];
for (ObjectZ *objectZ in anotherObjectArray) {
    [tagDictionary setObject:objectZ.tag forKey:objectZ.tag];
    }
for (ObjectA *objectA in objectsArray) {
    if ([tagDictionary objectForKey:objectA.tag]) {
        [direction addObject:objectA];
    }
}
...