8

我已经看到很多按键对字典进行排序,然后获取值的示例,但是我将如何按值排序。

例如

{
blue:12;
red:50;
white:44;
}

我希望这些按数字降序排序:

{
red:50;
white:44;
blue:12
}

我尝试获取一个排序的 nsarray 键,我可以从中创建有序的 nsarray,但结果似乎仍然是无序的。

  NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) {

    if ( first < second ) {
        return (NSComparisonResult)NSOrderedAscending;
    } else if ( first > second ) {
        return (NSComparisonResult)NSOrderedDescending;
    } else {
        return (NSComparisonResult)NSOrderedSame;
    }

  }];
4

3 回答 3

10

从概念上讲,NSDictionary 是未排序的,正如 C0deH4cker 已经说过的那样。

如果您需要订单,您可以将键写入数组(但在从字典中删除键后,数组保留它可能会遇到问题,但是有教程如何使用CFArray)或NSSortedSet

或者你可以继承 NSDictionary——这不是很简单,因为 NSDictionary 是一个类集群。但幸运的是,Matt 在他精彩的博文“OrderedDictionary: Subclassing a Cocoa class cluster”中展示了如何使用一个小技巧,即覆盖的has-a关系。


请注意,您的代码

 NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) {

    if ( first < second ) {
        return (NSComparisonResult)NSOrderedAscending;
    } else if ( first > second ) {
        return (NSComparisonResult)NSOrderedDescending;
    } else {
        return (NSComparisonResult)NSOrderedSame;
    }

  }];

当您将 C 运算符应用于对象时,不会做您希望它做的事情。现在他们的指针将被排序。

它应该是这样的

 NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) {
    return [first compare:second];
  }];

或者,如果您想订购标量,即作为对象的包装器(即 NSNumber)

 NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 
    if ([first integerValue] > [second integerValue]) 
        return (NSComparisonResult)NSOrderedDescending;

    if ([first integerValue] < [second integerValue])
        return (NSComparisonResult)NSOrderedAscending;
    return (NSComparisonResult)NSOrderedSame;
}];
于 2012-06-26T23:55:15.277 回答
0

根据定义,字典是无序的。使用哈希表访问它们以提高速度。您能够“订购”它的唯一方法是选择不同的数据类型。bas 数据类型取决于您的意图。

于 2012-06-26T23:39:12.087 回答
0

或者您可以直接对您的 NSString 键进行排序,例如:

NSArray* sortedKeys = [sortedKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id  _Nonnull obj2) {
        NSNumber *A = @([obj1 LongValue]);
        NSNumber *B = @([obj2 LongValue]);

        return [A compare:B];
    } ];
于 2015-12-18T06:28:30.817 回答