I need to find the most common (modal) elements in an array.
The simplest way I could think of was to set variables for each unique element, and assign a count variable for each one, which increases every time it is recorded in a for loop which runs through the array.
Unfortunately the size of the array is unknown and will be very large, so this method is useless.
I have come across a similar question in Objective-C that uses an NSCountedSet method to rank the array elements. Unfortunately I am very new to programming, and could only translate the first line into Swift.
The suggested method is as follows:
var yourArray: NSArray! // My swift translation
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:yourArray];
NSMutableDictionary *dict=[NSMutableDictionary new];
for (id obj in set) {
[dict setObject:[NSNumber numberWithInteger:[set countForObject:obj]]
forKey:obj]; //key is date
}
NSLog(@"Dict : %@", dict);
NSMutableArray *top3=[[NSMutableArray alloc]initWithCapacity:3];
//which dict obj is = max
if (dict.count>=3) {
while (top3.count<3) {
NSInteger max = [[[dict allValues] valueForKeyPath:@"@max.intValue"] intValue];
for (id obj in set) {
if (max == [dict[obj] integerValue]) {
NSLog(@"--> %@",obj);
[top3 addObject:obj];
[dict removeObjectForKey:obj];
}
}
}
}
NSLog(@"top 3 = %@", top3);
In my program I will need to find the top five place names in an array.
edit: now with Swift 2.0 below
Not the most efficient of solutions but a simple one:
descending
now consists of an array of pairs: the value and the frequency, sorted most frequent first. So the “top 5” would be the first 5 entries (assuming there were 5 or more distinct values). It shouldn't matter how big the source array is.Here's a generic function version that would work on any sequence:
For Swift 2.0, you can adapt the function to be a protocol extension:
For Swift 3.0: