所以我有一个类似于此的NSNumber字典(已经按顺序添加了键):
1 : @2000,
2 : @2000,
4 : @1000,
5 : @1000,
6 : @3000
我希望值和键都按升序排序,值的顺序具有更高的优先级。 (由于字典没有像@rmaddy所提到的那样排序,因此得到的有序键和值在单独的数组中)。 结果应该是:
4 : 1000,
5 : 1000,
1 : 2000,
2 : 2000,
6 : 3000
我已经可以使用
获取按值排序的键NSArray<NSNumber *> *sortedKeys = [dict keysSortedByValueUsingSelector:@selector(compare:)];
但这当然不尊重键的顺序。
免责声明:Swift中已解决此问题的解决方案here但我无法弄清楚如何在Obj-C中实现
答案 0 :(得分:1)
好的,您需要两个单独的数组,其中一个是字典的排序值,另一个是排序以与值对应的键。此外,与相同值关联的两个键应按两个键的自然顺序排序。
对值进行排序很容易。但是没有任何内置功能可以按照您想要的方式对相应的键进行排序。问题是获取按键顺序排序的相等值的键。下面的代码是一个可以产生预期结果的解决方案。
NSDictionary *dict = @{@1 : @2000,
@2 : @2000,
@4 : @1000,
@5 : @1000,
@6 : @3000};
NSArray *sortedValues = [dict.allValues sortedArrayUsingSelector:@selector(compare:)];
NSOrderedSet *uniqueValues = [NSOrderedSet orderedSetWithArray:sortedValues];
NSMutableArray *sortedKeys = [NSMutableArray arrayWithCapacity:dict.count];
for (id val in uniqueValues) {
NSArray *keys = [dict allKeysForObject:val];
[sortedKeys addObjectsFromArray:[keys sortedArrayUsingSelector:@selector(compare:)]];
}
NSLog(@"dict: %@", dict);
NSLog(@"keys: %@, values: %@", sortedKeys, sortedValues);
输出:
dict: { 6 = 3000; 2 = 2000; 5 = 1000; 1 = 2000; 4 = 1000; } keys: ( 4, 5, 1, 2, 6 ), values: ( 1000, 1000, 2000, 2000, 3000 )
答案 1 :(得分:1)
我从一个可排序的数据结构开始:
NSDictionary *d = @{@1 : @2000,
@2 : @2000,
@4 : @1000,
@5 : @1000,
@6 : @3000};
NSMutableArray *array = [[NSMutableArray alloc] init];
for (id key in [d allKeys]) {
[array addObject:@[key, d[key]]];
}
这会给我们:
@[ @[@6, @3000], @[@2, @2000], ...]
现在,我们可以编写一个比较器来比较你喜欢的。我从OP中理解的是,我们希望对键进行主要排序,并对键进行次要(打破平局)排序:
[array sortUsingComparator:^NSComparisonResult(id elementA, id elementB) {
NSNumber *valueA = ((NSArray *)elementA)[1];
NSNumber *valueB = ((NSArray *)elementB)[1];
if ([valueA isEqualToNumber:valueB]) {
NSNumber *keyA = ((NSArray *)elementA)[0];
NSNumber *keyB = ((NSArray *)elementB)[0];
return [keyA compare:keyB];
} else {
return [valueA compare:valueB];
}
}];
NSLog(@"%@", array);