6 Replies - 837 Views - Last Post: 28 April 2013 - 03:52 AM Rate Topic: -----

#1 lifeinbinary  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 160
  • Joined: 15-February 11

Sorting NSDictionary items

Posted 25 April 2013 - 12:45 AM

I've been trying to get an NSDictionary sorted by int value but no matter what I do the Dictionary sorts by key value! I'll show the different things I've tried but they all give the same result. Yesterday I needed to sort dice rolls and was successful, but today I need the value to be associated with a player (thus the need for NSDictionary). If I need to resort to creating my own tuple and implementing my own quicksort to solve such a menial task I will be sorely dissapointed ;)

So first the entries into the NSDictionary... (this is tested and working as expected)

case TurnOrderBidding:
                    
                    [self.match.state.turnBids setObject:[NSNumber numberWithInt:self.match.state.numberFieldInt] forKey:[HelperFunctions formatTypeToString:self.match.state.currentPlayer.playerID]];
                    
                    NSLog(@"Bid added from %@: %d", [HelperFunctions formatTypeToString:self.match.state.currentPlayer.playerID],
                          [(NSNumber *)[self.match.state.turnBids objectForKey:[HelperFunctions formatTypeToString:self.match.state.currentPlayer.playerID]] intValue]);
                    
                    if(self.match.state.turnBids.count == self.match.state.players.count)
                    {
                        [self.match setTurnOrder];
                        
                        NSLog(@"Keys in order:%@", self.match.state.turnBids);
                    }
                    else
                    {
                        [self.match.state setNumberFieldInt:0];
                        [self.numberFieldLabel.label setString:[NSString stringWithFormat:@"%d",self.match.state.numberFieldInt]];
                        [self.match nextPlayer];
                    }
                    break;



And here is the setTurnOrder method:

-(void)setTurnOrder
{

    self.state.turnOrder = [self.state.turnBids keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
        
        NSLog(@"Comparing: %d and %d",[obj1 integerValue] , [obj2 integerValue]);
        
        if ([obj1 integerValue] > [obj2 integerValue])
        {
            NSLog(@"Returning: %d", (NSComparisonResult)NSOrderedDescending);
            return (NSComparisonResult)NSOrderedDescending;
        }
        
        if ([obj1 integerValue] < [obj2 integerValue])
        {
            NSLog(@"Returning: %d", (NSComparisonResult)NSOrderedAscending);
            return (NSComparisonResult)NSOrderedAscending;
        }
    
        NSLog(@"Returning: %d", (NSComparisonResult)NSOrderedAscending);
        return (NSComparisonResult)NSOrderedSame;

    }];
}



Here is the output for the above...

2013-04-25 04:36:01.296 2210[4984:c07] Bid added from Yellow: 2
2013-04-25 04:36:06.346 2210[4984:c07] Bid added from Red: 1
2013-04-25 04:36:10.897 2210[4984:c07] Bid added from Black: 4
2013-04-25 04:36:16.697 2210[4984:c07] Bid added from Green: 3
2013-04-25 04:36:16.698 2210[4984:c07] Comparing: 4 and 2
2013-04-25 04:36:16.698 2210[4984:c07] Returning: 1
2013-04-25 04:36:16.699 2210[4984:c07] Comparing: 3 and 1
2013-04-25 04:36:16.699 2210[4984:c07] Returning: 1
2013-04-25 04:36:16.700 2210[4984:c07] Comparing: 2 and 1
2013-04-25 04:36:16.700 2210[4984:c07] Returning: 1
2013-04-25 04:36:16.701 2210[4984:c07] Comparing: 2 and 3
2013-04-25 04:36:16.702 2210[4984:c07] Returning: -1
2013-04-25 04:36:16.702 2210[4984:c07] Comparing: 4 and 3
2013-04-25 04:36:16.702 2210[4984:c07] Returning: 1
2013-04-25 04:36:16.703 2210[4984:c07] Keys in order:{
Black = 4;
Green = 3;
Red = 1;
Yellow = 2;
}


As you can see it seems like it's sorting the values (the comparing/returning output) but it just ends up sorting the keys by alphabetical order instead of sorting them by the value (bid) associated with the key. What am I missing here?

Sam

OMG! I was printing out the wrong array for the results! It's been working this whole time! Time for bed :D

Is This A Good Question/Topic? 0
  • +

Replies To: Sorting NSDictionary items

#2 lifeinbinary  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 160
  • Joined: 15-February 11

Re: Sorting NSDictionary items

Posted 25 April 2013 - 01:13 AM

Now that I have the NSDictionary items sorted by value with this code:

-(void)setTurnOrder
{

    self.state.turnOrder = [self.state.turnBids keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
        
        if ([obj1 integerValue] > [obj2 integerValue])
        {
            return (NSComparisonResult)NSOrderedDescending;
        }
        
        if ([obj1 integerValue] < [obj2 integerValue])
        {
            return (NSComparisonResult)NSOrderedAscending;
        }
        
        return (NSComparisonResult)NSOrderedSame;

    }];
}



I need to deal with values being equal. The game rules state that when bids are equal, all players with equal bids roll a die to determine the order of that subset of players. Ex:

Player 1 bids 2
Player 2 bids 1
Player 3 bids 2
Player 4 bids 3
Player 5 bids 2

Then players 1, 3 and 5 would roll a die to determine their order so if they roll:

Player 1 rolls 5
Player 3 rolls 2
Player 5 rolls 2

Then again

Player 3 rolls 4
Player 5 rolls 3

The final order of play would be:

Player 4
Player 1
Player 3
Player 5
Player 2

I can see that the way keysSortedByValueUsingComparator: compares two elements at a time then uses some sort algorithm internally so modifying my above code like this would not produce the desired results:

 -(void)setTurnOrder
{

    self.state.turnOrder = [self.state.turnBids keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
        

        while ([obj1 integerValue] == [obj2 integerValue])
        {
            // Roll dice until one obj is higher than the other
        }

        if ([obj1 integerValue] > [obj2 integerValue])
        {
            return (NSComparisonResult)NSOrderedDescending;
        }
        
        if ([obj1 integerValue] < [obj2 integerValue])
        {
            return (NSComparisonResult)NSOrderedAscending;
        }

    }];
}



Any ideas on a solution for this? I'm sure a fresh mind after some sleep will let me sove this somehow but I'm sure it won't be elegant and I'd like to see how you pros would do it :)

Good night!
Was This Post Helpful? 0
  • +
  • -

#3 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Sorting NSDictionary items

Posted 27 April 2013 - 10:26 PM

The answer is on this page. As I always tell people, always refer to the docs!
Was This Post Helpful? 1
  • +
  • -

#4 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Sorting NSDictionary items

Posted 27 April 2013 - 10:28 PM

Answered in your last thread. Can you think of a way of handling equal values when sorting?
Was This Post Helpful? 0
  • +
  • -

#5 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10810
  • View blog
  • Posts: 40,294
  • Joined: 27-December 08

Re: Sorting NSDictionary items

Posted 27 April 2013 - 10:31 PM

Duplicate threads merged. Please avoid duplicate posting.
Was This Post Helpful? 0
  • +
  • -

#6 lifeinbinary  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 160
  • Joined: 15-February 11

Re: Sorting NSDictionary items

Posted 28 April 2013 - 12:16 AM

View PostButchDean, on 27 April 2013 - 10:26 PM, said:

The answer is on this page. As I always tell people, always refer to the docs!

Thanks for the link, I havn't had time to read it carefully but it seems like it will elaborate on the internal sort method of NSDictionary thus allowing me to implement a response to items being equal. On the other hand, perhaps it would be easier to simply let the dictionary set the items as equal (ie. return (NSComparisonResult)NSOrderedSame;) and then recursively deal with the sets of equal items by ranomizing their values and sorting the subset of those dictionary items until all dictioanry items are unique and sorted. What do you think?
Was This Post Helpful? 0
  • +
  • -

#7 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Sorting NSDictionary items

Posted 28 April 2013 - 03:52 AM

Go with the reliable method in the link, it has been implemented as part of the framework for good reasons.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1