I have an array of values where I would like to count the incidence of each unique value and then create a new array of unique value sorted by incidence.
For example, for the Array as follows:
vals = {0,0,0,2,0,1,2}
I would like to end up with array of {0,2,1}
since 0 is the most common value, 2 is the second most common and 1 is the least common. Note, the fact that these are numbers is irrelevant. They could just as easily be strings.
I thought I might be able to use an nssortdescriptor as in:
NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"wordCount" ascending:NO];
NSArray *sortedcats = [vals sortedArrayUsingDescriptors:@[sorter]];
However, this is not sorting them by incidence and it also does not filter out duplicates.
Thanks for any suggestions.
There's a couple of approaches
Convert to a Set/NSSet
then sort.
Swift
let vals = [0,0,0,2,0,1,2]
let uniqued = Set(vals).sorted()
That same method would also work with NSSet
+ NSSortDescriptor
in Objective C but obviously a longer line to write.
or a more classic Foundation approach
let nsvals: NSArray = [3,0,0,2,0,1,2]
let nsuniquedAndSorted = nsvals.value(forKeyPath: "@distinctUnionOfObjects.self")
Which is kind of cool as @distinctUnionOfObjects
also sorts for free. There's lots of clever key-value tricks in the same vein here.
EDIT
To sort by incidence an approach could be to count the uniques then resort on that basis.
let sortedByIncidence = uniqued
.map { outer in return (outer, vals.filter({$0 == outer}).count) }
.sorted { $0.1 > $1.1 }
.map { $0.0 }