0

У меня есть словарь, содержащий события. Формат для одного события выглядит следующим образомЭффективный способ узнать, имеет ли словарь более двух одинаковых значений

{ 
    eventTime = 53'; 
    eventType = "Yellow Card"; 
    gameID = 0; 
    name = Mike; 
    selectedTeam = homeTeam; 
} 

И я спас все события в NSMutableArray. Клиенты будут вставлять события со временем (для футбольной игры). Теперь мне нужно проверить при заполнении моего UITableView, если у игрока есть две желтые карточки, поэтому я могу изменить изображение на другое изображение. То, как я делаю это сейчас, выглядит так, и мне это не очень нравится, и на самом деле это не работает.

if ([typeEvent isEqualToString:@"Yellow Card"]){ 
    int i= 0; 
    for (id obj in _events) 
    { 
     if ([[obj valueForKeyPath:[NSString stringWithFormat:@"eventType"]] isEqualToString:@"Yellow Card"] && [[obj valueForKeyPath:[NSString stringWithFormat:@"name"]] isEqualToString:[gameInfoObject valueForKeyPath:[NSString stringWithFormat:@"name"]]]) { 
      i++; 
      if (i >= 2) { 
       imageType = [UIImage imageNamed:@"Yellow&Red.png"]; 
      } 
     } 
    } 
} 

и в моем UITableView я делаю это так, вы знаете, что это то, что в приведенном выше

NSMutableDictionary *gameInfoObject =[_events objectAtIndex:indexPath.row]; 

Так в основном коде, если есть больше чем 1 событие в СОБЫТИЙ массиве, где типСобытия равно «Yellow Card "и название этих матчей мне нужно изменить изображение в„Желтый & Красный“

Спасибо вам помочь

+1

Не имеет отношения к вашему вопросу, но: '[NSString stringWithFormat: @" StringWithNoFormattingSpecifiers "]' является просто дорогим способом записи '@" StringWithNoFormattingSpecifiers ". Не используйте '-valueForKeyPath:' с пути, который, как вы знаете, имеет только один элемент. Вы можете использовать '-valueForKey:', но не делайте этого, когда ключ жестко закодирован. Для словаря используйте '-objectForKey:'. Для других объектов просто вызовите getter для свойства. –

+0

Спасибо, что указали это! Я получил, что я должен изменить его на объект для ключа, но я не понял, как реализовать @ "StringWithNoFormattingSpecifiers". Пример, как бы выглядела эта строка ?: [[obj objectForKey: [NSString stringWithFormat: @ "eventType"]] @KenThomases –

+0

[obj objectForKey: [NSString stringWithFormat: @ "eventType"]] может быть написано: obj [@ "eventType "] в современной Objective-C – dirkgroten

ответ

0

Я бы начал с использования одного из быстрых методов перечисления, предоставленного NSArray.

NSIndexSet *matchingSet = [_events indexesOfObjectsPassingTest:^BOOL(id obj, 
            NSUInteger idx, 
            BOOL *stop){ 
    return ([gameInfoObject[@"name"] isEqualToString:obj[@"name"] && [obj[@"eventType"] isEqualToString:@"Yellow Card"]) 
    }]; 

if (matchingSet.count >= 2) { 
    imageType = [UIImage imageNamed:@"Yellow&Red.png"]; 
} 
+0

Этот ответ остается ближайшим к его первоначальному источнику. –

0

Посмотрите в использовании NSCountedSet для ваших объектов. Вы получите постоянный поиск времени и счет.

0

Вы могли бы сделать это несколькими путями. Лично я считаю, что наличие объекта события будет наиболее читаемым для вашего кода, но если вы хотите использовать простые объекты, такие как NSArray и NSDictionary, вы можете легко решить это с помощью двух дополнительных NSMutableArray или одного дополнительного NSMutableDictionary или одного дополнительного NSCountedSet.

NSMutableSet s:

NSMutableSet *yellowCardPlayers; 
NSMutableSet *redCardPlayers; 

- (void)receiveEvent:(NSDictionary *)event { 
    [_events addObject:event]; 
    if ([event[@"eventType"] isEqualToString:@"Yellow Card"]) { 
    if ([yellowCardPlayers containsObject:event[@"name"]]) { 
     if ([redCardPlayers containsObject:event[@"name"]]) { 
     // How did a player get a yellow card after already being ejected from the game?! :) 
     } else { 
     [redCardPlayers addObject:event[@"name"]]; 
     } 
    } else { 
     [yellowCardPlayers addObject:event[@"name"]]; 
    } 
    } 
} 

NSMutableDictionary:

NSMutableDictionary *playerYellowCards; 

- (void)receiveEvent:(NSDictionary *)event { 
    [_events addObject:event]; 
    if ([event[@"eventType"] isEqualToString:@"Yellow Card"]) { 
    NSNumber *numberOfYellowCards = [playerYellowCards objectForKey:event[@"name"]]; 
    if (![[playerYellowCards allKeys] containsObject:event[@"name"]]) { 
     [playerYellowCards addObject:@(1) forKey:event[@"name"]]; 
    } else { 
     [playerYellowCards addObject:@([playerYellowCards[event[@"name"]] integerValue]+1) forKey:event[@"name"]]; 
    } 
    } 
} 

NSCountedSet:

NSCountedSet *playerYellowCards; 

- (void)receiveEvent:(NSDictionary *)event { 
    [_events addObject:event]; 
    if ([event[@"eventType"] isEqualToString:@"Yellow Card"]) { 
    [playerYellowCards addObject:event[@"name"]]; 
    } 
} 
0

Используйте NSPredicate фильтровать массив, а затем подсчитать результаты:

NSPredicate *yellowFlagFilter = [NSPredicate predicateWithFormat:@"eventType == %@ AND name == %@",@"Yellow Card", gameInfoObject.name]; 
NSArray *yellowCards = [_events filteredArrayUsingPredicate:yellowFlagFilter]; 
if ([yellowCards count] > 1) { 
    imageType = [UIImage imageNamed:@"Yellow&Red.png"]; 
}