Sort by the mode in an Array in Objective-C iPhone
If I have an NSArray with some values in them. Is there a way using descriptors to sort it by the most frequent number in the array first and the least frequent number at the end,
Array has(
"3",
"2",
"1",
"3",
"3",
"7",
开发者_开发技巧)
to
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]);
Not without some additional data structures.
All the NSArray sorting operations (sortUsingDescriptors:, sortedArrayUsingSelector:, etc.) assume that you can look at two elements "a" and "b" and determine if "a < b" without looking at any other elements in the NSArray.
One solution would be to create a new Array whose member objects contain both the value and the frequency count (use an NSDictionary to efficiently count how many rows there are for each value). For example:
Array( // {value, frequency}
{3,3},
{2,1},
{1,1},
{3,3},
{3,3},
{7,1}
)
Then it's easy to use a descriptor to sort that array by frequency.
精彩评论