NSDictionary键按值以数字排序

时间:2009-10-25 04:28:25

标签: objective-c cocoa-touch sorting nsdictionary

我将名称作为键存储,并将值作为值存储到NSDictionary中,以便保存在NSUserDefaults中。然后我想要取回按分数排序的键,但我似乎无法用数字排序它们,只能用字符串。例如,分数列表100,50,300,200,500可以给我100,200,300,50,500。

可以这样做还是我需要以不同的方式解决这个问题?

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:)];

6 个答案:

答案 0 :(得分:7)

如何使用keysSortedByValueUsingSelector(NSDictionary)

根据XCode中的文档

,似乎是您所需要的

答案 1 :(得分:5)

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:)];

答案 2 :(得分:3)

@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:)];

我仍然对上一行感到困惑?

我只是使用

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

数字数组是否正常,还是有更简单的方法?

非常感谢...

答案 3 :(得分:2)

-compare:是一个字符串比较。通过不同的方法进行比较,例如:

@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

在您的特定情况下,您可以使用-intValue。

答案 4 :(得分:0)

不确定它会有所帮助,但您也可以将NSArray保存在plist中;与NSDictionary(以基本上随机的顺序返回键)不同,你可以在放入它们时将它们取回。

答案 5 :(得分:0)

我认为这个问题的最简单方法是使用比较器..

NSString *defaultNames[] = {@"Matt", @"Terry",@"Jessica",@"Sean",nil};
NSNumber *defaultScores[] = {@(600), @(500),@(400),@(50), nil};
NSDictionary *newScoreDict =  [NSDictionary dictionaryWithObjects:defaultNames       forKeys:defaultScores count:4];
NSArray *currScores = [newScoreDict keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    if ([obj1 integerValue] > [obj2 integerValue]) {
        return NSOrderedAscending;
    }else{
        return NSOrderedDescending;
    }}];

for (NSString *string in currScores) {
    NSLog(@"%@",string);
}

试试这个.. 我注意到我无法通过使用NSNumber对象达到值,所以如果你想达到对象值而不是我解决了将NSNumber分数更改为NSString并在订购时将它们转换为数字。你可以使用如下..

NSString *defaultNames[] = {@"Matt", @"Terry",@"Jessica",@"Sean",nil};
NSString *defaultScores[] = {@"600", @"500",@"400",@"50", nil};
NSMutableDictionary *newScoreDict =  [NSMutableDictionary   dictionaryWithObjects:defaultScores  forKeys:defaultNames count:4];

NSArray *currScores = [newScoreDict keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *number1 = [formatter numberFromString:obj1];
NSNumber *number2 = [formatter numberFromString:obj2];
    if (number1.intValue > number2.intValue) {
        return NSOrderedDescending;
    }else{
        return NSOrderedAscending;
    }}];

for (NSString *name in currScores) {
    NSLog(@"key %@ value %@",name,[newScoreDict valueForKey:name]);
}

希望有所帮助......