objective-c NSDictionary 键按数值排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1620001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:24:16  来源:igfitidea点击:

NSDictionary keys sorted by value numerically

objective-ccocoa-touchsortingnsdictionary

提问by Matt

I store names as keys and scores as values into an NSDictionaryfor 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.

我将名称作为键和分数作为值NSDictionary存储到NSUserDefaults. 然后我想取回按分数排序的键,但我似乎无法按数字对它们进行排序,只能按字符串排序。例如,分数 100、50、300、200、500 的列表给我 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:)];

回答by leukosaima

how about using keysSortedByValueUsingSelector (NSDictionary)

如何使用 keysSortedByValueUsingSelector (NSDictionary)

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

根据 XCode 中的文档,似乎是您所需要的

回答by Black Tiger

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

回答by Bill Hernandez

@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...

非常感谢您...

回答by NSResponder

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

-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

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

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

回答by David Dunham

Not sure it would help, but you can also save an NSArray in a plist; unlike an NSDictionary (which returns keys in essentially random order), you get them back as you put them in.

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

回答by mert

I think simplest way of this question is using comparator..

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

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);
}

try this.. I noticed that i couldnt reach value with using NSNumber object so if you want to reach object value than i solved with changing your NSNumber scores to NSString and convert them to numbers while ordering. You can use like below..

试试这个..我注意到我无法通过使用 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]);
}

Hope it helps..

希望能帮助到你..