Objective-C 中 sortedArrayUsingComparator 的意外结果

Unexpected result with sortedArrayUsingComparator in Objective-C

我正在尝试对 NSMutableDictionary 的键及其各自的值进行排序(值按升序排列)。我的代码片段如下:

NSArray *sortedKeysWithValues = [[myDict allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
return [[myDict objectForKey:obj2] compare:[myDict objectForKey:obj1]];}];

NSMutableDictionary的内容是:

{
 806: "-89.06";
 802: "-75.12";
 837: "-77.76";
 803: "-84.75";
 808: "-115";
 804: "-102.12";
 813: "-115";
 805: "-115";
 801: "-67.53";
 836: "-70.36";
}

以上代码执行后,sortedKeyWithValues上的内容变为:

(
806,
803,
837,
802,
836,
801,
808,
813,
805,
804,
) 

请注意,具有最高值的键位于 sortedKeyWithValues5th 索引处。 2nd 最高值的键在 4th 索引上,依此类推。它一直持续到第一个索引。值位于第一个索引旁边的键位于 sortedKeyWithValues 的最后一个索引,它上升到第 6 个索引。

我期望 sortedKeyWithValues 处的对象顺序是:

(
801,
836,
802,
837,
803,
806,
804,
805,
813,
808,
)

使用 sortedArrayUsingComparator 时出现这种奇怪结果的原因可能是什么?是因为方法的错误还是我这边的一些愚蠢的错误?

谢谢!

只有几个注释:

1) myDict里面的比较回调是什么?

2) 在回调中,您通常必须获取 obj1 / obj2 中的值并比较其中的数据成员: (最终铸造它们......) 例如:

NSArray *sortedPeople = [self.persons sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){

Person *p1 = (Person *)obj1;
Person *p2 = (Person *)obj2;
    return [p1.surname compare:p2.surname];

}];

所以我需要知道你为什么使用 MyDict。

发生这种情况是因为 NSDictionary 的值为 NSStringscompare: 正在按字母顺序排序。

根据您的代码快速修复:

NSArray *sortedKeysWithValues = [[dic allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
    return [@([dic[obj2] doubleValue]) compare:@([dic[obj1] doubleValue])];}];

这不是错误。您比较的是字符串而不是数字。

NS(Mutable)Dictionary 有一个专用方法 keysSortedByValueUsingSelector 按值对键进行排序,选择器 localizedStandardCompare 按数字对字符串进行排序。 comparator API 不需要。

NSArray *sortedKeysWithValues = [myDict keysSortedByValueUsingSelector:@selector(localizedStandardCompare:)];

或者使用带有选项 NSNumericSearch

的比较器
id numericSort = ^(NSString * key1, NSString * key2) {
    return [key1 compare:key2 options: NSNumericSearch];
};

NSArray *sortedKeysWithValues = [dictionary keysSortedByValueUsingComparator:numericSort];

尝试这样做:

NSArray *myArray;

myArray = [myDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) {

     if ([obj1 doubleValue] > [obj2 doubleValue]) {

          return (NSComparisonResult)NSOrderedDescending;
     }
     if ([obj1 doubleValue] < [obj2 doubleValue]) {

          return (NSComparisonResult)NSOrderedAscending;
     }

     return (NSComparisonResult)NSOrderedSame;
}];