Shorty07 Shorty07 - 1 month ago 16
iOS Question

Max value for each object in an Array of Dictionaries

I have an array of dictionaries that I am trying to get the Max score for each player in the array. Each player can have multiple entries I am trying to get an array of dictionaries of each players best score.

NSArray
[0] - NSDictionary

- [0] Score: (double)20.7
- [1] NameID: (int) 1
- [2] Date


[1] - NSDictionary

- [0] Score: (double)25
- [1] NameID: (int) 1
- [2] Date


[2] - NSDictionary

- [0] Score: (double)28
- [1] NameID: (int) 2
- [2] Date


[3] - NSDictionary`

- [0] Score: (double)26
- [1] NameID: (int) 3
- [2] Date


I have tried using NSPredicate predicateWithFormat but I am only able to get back the max for everything in the array not related to the name.

Expected Output:

NSArray
[1] - NSDictionary

- [0] Score: (double)25
- [1] NameID: (int) 1
- [2] Date


[2] - NSDictionary

- [0] Score: (double)28
- [1] NameID: (int) 2
- [2] Date


[3] - NSDictionary`

- [0] Score: (double)26
- [1] NameID: (int) 3
- [2] Date


Thanks for the help.

Answer

You can't use an NSPredicate for this, since you want to determine the maximum score for several different players. Under the covers, NSPredicate iterates the array anyway, so using your own loop isn't any less efficient. In the following code I have assumed that the scores and player names are wrapped in NSNumber

-(NSArray *)maxScoresForPlayers:(NSArray *)playerScores {

    NSMutableDictionary *maxScores = [NSMutableDictionary new];

    for (NSDictionary *player in playerScores) {
        NSNumber *playerID = (NSNumber *)player[@"NameID"];
        NSDictionary *playerMax = maxScores[playerID];
        if (playerMax == nil) {
           playerMax = player;
        } else {
           NSNumber *currentMax = (NSNumber *)[playerMax[@"Score"];
           NSNumber *playerScore = (NSNumber *)player[@"Score"];
           if ([playerScore doubleValue] > [currentMax doubleValue]) {
                playerMax = player;
           }
        }
        maxScores[playerID] = playerMax;
    }

    return([maxScores allValues];
}