如果我有一个包含一些值的 NSArray。有没有办法使用描述符将它按数组中最频繁的数字排在最前面,最不频繁的数字排在最后,
Array has(
"3",
"2",
"1",
"3",
"3",
"7",
)
到
Array has(
"3",
"3",
"3",
"1",
"2",
"7",
)
@interface NSArray (Ext)
-(NSArray*) sortByMostFrequent ;
@end
@implementation NSArray (Ext)
-(NSArray*) sortByMostFrequent {
NSMutableDictionary* frequencyDict = [NSMutableDictionary dictionary];
for (id obj in self) {
int frequency = [[frequencyDict valueForKey:obj] intValue];
[frequencyDict setValue:[NSNumber numberWithInt:frequency+1] forKey:obj];
}
NSMutableArray* ary = [NSMutableArray arrayWithCapacity:self.count];
for (id obj in self) {
[ary addObject:[NSDictionary dictionaryWithObjectsAndKeys:
obj, @"Object",
[frequencyDict valueForKey:obj], @"Frequency",
nil]];
}
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Frequency" ascending:NO];
[ary sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
return [ary valueForKey:@"Object"];
}
@end
/// example
NSArray* ary = [NSArray arrayWithObjects:@"3", @"2", @"1", @"3", @"3", @"7", nil];
NSLog(@"ary %@", [ary sortByMostFrequent]);
并非没有一些额外的数据结构。
所有 NSArray 排序操作(sortUsingDescriptors:、sortedArrayUsingSelector: 等)都假定您可以查看两个元素“a”和“b”并确定“a < b”是否“a < b”,而无需查看 NSArray 中的任何其他元素。
一种解决方案是创建一个新的 Array,其成员对象同时包含值和频率计数(使用 NSDictionary 有效地计算每个值有多少行)。例如:
Array( // {value, frequency}
{3,3},
{2,1},
{1,1},
{3,3},
{3,3},
{7,1}
)
然后很容易使用描述符按频率对该数组进行排序。