Как найти, если массив содержит объект (без использования цикла for)? - PullRequest
1 голос
/ 17 октября 2011

Я использую приведенный ниже код, чтобы проверить, что массив ary_navigationControllerViews содержит объект myclass или не работает нормально, но мне нужно без цикла for. Я знаю, что у нас есть метод, как containsObject, но как использовать в этой ситуации.Есть ли способ проверить это условие без использования цикла for.

NSArray *ary_navigationControllerViews = [[NSArray alloc] initWithArray:[self.navigationController viewControllers]];
    for(id obj_viewController in ary_navigationControllerViews) {
        if([obj_viewController isKindOfClass:[myClass  class]]) {
            //some my code
            return;
        }
    }

Ответы [ 4 ]

12 голосов
/ 17 октября 2011

NSPredicate делает этот вид заданий намного проще.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY SELF.class.description == %@", [[myClass class] description]];
BOOL exists =  [predicate evaluateWithObject:ary_navigationControllerViews];
if (exists) {
    //some my code
    return;
}

Чтобы получить экземпляр контроллера представления, вы можете использовать следующий код.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self.class.description == %@", [[self class] description]];
NSArray *vcs = [ary_navigationControllerViews filteredArrayUsingPredicate:predicate];
if ([vcs count] > 0) {
    id vc = [vcs objectAtIndex:0];
    // Now vc is the view controller you are looking for
}
3 голосов
/ 17 октября 2011

Или, основываясь на ответе Некто, вы также можете напрямую вернуть индекс следующим образом:

NSArray *arr = [NSArray arrayWithObjects:[NSString stringWithFormat:@"test"], [NSNumber numberWithInt:10], [NSNull null], nil];

int index = [arr indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
    if ([obj isKindOfClass:[NSNumber class]])
    {
        *stop = YES;
       return YES;
    }

    return NO;
}];
if (index != NSNotFound) 
{
    NSLog(@"contains at %d", index);
}

Наслаждайтесь.

3 голосов
/ 17 октября 2011

Вы можете использовать блоки:

NSArray *arr = [NSArray arrayWithObjects:[NSString stringWithFormat:@"test"], [NSNumber numberWithInt:10], [NSNull null], nil];
__block int index = NSNotFound;
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if ([obj isKindOfClass:[NSNumber class]])
    {
        index = idx;
        *stop = YES;
    }
}];
if (index != NSNotFound)
{
    NSLog(@"contains at %d", index);
}

Например, в вашем случае:

[ary_navigationControllerViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if ([obj isKindOfClass:[myClass class]])
    {
        //some my code
        *stop = YES;
    }
}];

Но я не думаю, что это уменьшит сложность вашего кода.Петли самые простые

1 голос
/ 17 октября 2011

Если вы действительно не можете использовать цикл for для этого, вам придется использовать метод, подобный indexesOfObjectsPassingTest:, который применяет блок к каждому объекту в массиве и возвращает NSIndexSet всех элементов в массив. Затем вы можете использовать это для возврата нового массива только объектов, которые проходят ваш тест:

check = ^ (id obj, NSUInteger idx, BOOL *stop) 
{
    return [obj isKindOfClass:[myClass class]];
};

NSIndexSet *objectsInMyClass = [[self.navigationController viewControllers] indexesOfObjectsPassingTest:check];

NSArray *filteredArray = [[self.navigationController viewControllers] objectsAtIndexes:objectsInMyClass];

Затем вы можете использовать makeObjectsPerformSelector или подобное, чтобы фактически выполнить ваш конкретный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...