Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDictionary keys sorted by value numerically

I store names as keys and scores as values into an NSDictionary for saving in NSUserDefaults. I then want to get back the keys sorted by score, but I can't seem to sort them numerically, only by string. The list of scores 100, 50, 300, 200, 500, for example, gives me 100, 200, 300, 50, 500.

Can this be done or do I need to go about this differently?

NSString *defaultNames[] = {@"Matt", @"Terry",@"Jessica",@"Sean",nil};
NSNumber *defaultScores[] = {@"600", @"500",@"100",@"50", nil};

NSDictionary *newScoreDict =  [NSDictionary dictionaryWithObjects:(id *)defaultScores forKeys:(id *)defaultNames count:7];

NSArray *currScores = [scoreDict keysSortedByValueUsingSelector:@selector(compare:)];
like image 778
Matt Avatar asked Oct 25 '09 04:10

Matt


People also ask

Is NSDictionary ordered?

NSDictionary keys & values are not ordered.

How do you set a value in NSDictionary?

You have to convert NSDictionary to NSMutableDictionary . You have to user NSMutableDictionary in place of the NSDictionary . After that you can able to change value in NSMutableDictionary . Save this answer.

What is NSDictionary in Objective c?

The NSDictionary class declares the programmatic interface to objects that manage immutable associations of keys and values. For example, an interactive form could be represented as a dictionary, with the field names as keys, corresponding to user-entered values.


4 Answers

how about using keysSortedByValueUsingSelector (NSDictionary)

Seems to be what you need as per the documentation in XCode

like image 192
leukosaima Avatar answered Oct 22 '22 01:10

leukosaima


NSString *defaultNames[] = {@"Matt", @"Terry",@"Jessica",@"Sean",nil};
NSNumber *defaultScores[] = {@"600", @"500",@"100",@"50", nil};
NSDictionary *newScoreDict =  [NSDictionary dictionaryWithObjects:(id *)defaultScores forKeys:(id *)defaultNames count:7];
NSArray *currScores = [scoreDict keysSortedByValueUsingSelector:@selector(localizedStandardCompare:)];
like image 43
Black Tiger Avatar answered Oct 22 '22 01:10

Black Tiger


@implementation NSString (numericComparison)

- (NSComparisonResult) floatCompare:(NSString *) other
{
    float myValue = [self floatValue];
    float otherValue = [other floatValue];
    if (myValue == otherValue) return NSOrderedSame;
    return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}

- (NSComparisonResult) intCompare:(NSString *) other
{
    int myValue = [self intValue];
    int otherValue = [other intValue];
    if (myValue == otherValue) return NSOrderedSame;
    return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}

@end

NSString *defaultNames[] = {@"Matt", @"Terry",@"Jessica",@"Sean",nil};
// NSNumber *defaultScores[] = {@"600", @"500",@"100",@"50", nil};

NSNumber *defaultScores[] = {                                                                   
            [NSNumber  numberWithInt:600],
            [NSNumber  numberWithInt:500],
            [NSNumber  numberWithInt:100],
            [NSNumber  numberWithInt:50],
            nil 
    };

NSDictionary *newScoreDict =  [NSDictionary dictionaryWithObjects:(id *)defaultScores forKeys:(id *)defaultNames count:4];

NSArray *currScores = [newScoreDict keysSortedByValueUsingSelector:@selector(intCompare:NotSureWhatGoesHere:)];

I am still confused with the previous line ?

Do I just use

//
NSArray *currScores = [newScoreDict keysSortedByValueUsingSelector:@selector(intCompare:other:)];
//

Is the array of numbers OK, or is there an easier way ?

Thank You Very Much...

like image 39
Bill Hernandez Avatar answered Oct 21 '22 23:10

Bill Hernandez


-compare: is a string compare. Pass a different method for the comparison, e.g:

@implementation NSString (numericComparison)

- (NSComparisonResult) compareNumerically:(NSString *) other
{
float myValue = [self floatValue];
float otherValue = [other floatValue];
if (myValue == otherValue) return NSOrderedSame;
return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}

@end

In your specific case, you could use -intValue instead.

like image 34
NSResponder Avatar answered Oct 22 '22 00:10

NSResponder