I've been using a website to calculate the frequency up until now but they have a maximum of 50,000 characters and now I need to do it myself which is really what I should have done from the start.
let frequencyCount = Dictionary(grouping: numbers) { $0 }
.mapValues{ $0.count }
mostFrequentTextView.text = String(format:"%@", frequencyCount)
let numbers = [
"1, 2, 3, 4",
"5, 6, 7, 8",
"3, 4, 5, 6",
"1, 2, 7, 8",
"1, 2, 3, 4",
"3, 4, 5, 6",
"1, 2, 3, 4",
"1, 2, 3, 4",
"5, 6, 7, 8",
"3, 4, 5, 6",
"1, 2, 7, 8",
"1, 2, 3, 4",
"3, 4, 5, 6",
"1, 2, 3, 4" ]
//Current result ↓
{
"1, 2, 3, 4" = 6;
"1, 2, 7, 8" = 2;
"3, 4, 5, 6" = 4;
"5, 6, 7, 8" = 2;
}
//Desired result ↓
1, 2, 3, 4 X 6 43%
3, 4, 5, 6 X 4 29%
1, 2, 7, 8 X 2 14%
5, 6, 7, 8 X 2 14%
Once grouped then you can use sorted
and reduce
to build the output
let output = frequencyCount.sorted(by: {$0.value > $1.value}).reduce(into: "") {
let fraction = Int(round(100.0 * Double($1.value) / Double(numbers.count)))
$0 += "\($1.key) X \($1.value) \(fraction)%\n"
}
Output
1, 2, 3, 4 X 6 43%
3, 4, 5, 6 X 4 29%
1, 2, 7, 8 X 2 14%
5, 6, 7, 8 X 2 14%
If you prefer String.format()
let fraction = round(100.0 * Double($1.value) / Double(numbers.count))
$0 += String(format: "%@ X %d %.0f%%\n", $1.key, $1.value, fraction)
Complete code if you want to put everything together
let total = Double(numbers.count)
let output = Dictionary(grouping: numbers) { $0 }
.mapValues{ $0.count }
.sorted(by: {$0.value > $1.value})
.reduce(into: "") {
$0 += "\($1.key) X \($1.value) \(Int(round(100.0 * Double($1.value) / total)))%\n"
}