Getting the most frequent value of an array
let myArray = [4, 4, 4, 3, 3, 3, 4, 6, 6, 5, 5, 2]
// Create dictionary to map value to count
var counts = [Int: Int]()
// Count the values with using forEach
myArray.forEach { counts[$0] = (counts[$0] ?? 0) + 1 }
// Find the most frequent value and its count with max(by:)
if let (value, count) = counts.max(by: {$0.1 < $1.1}) {
print("\(value) occurs \(count) times")
}
Output:
4 occurs 4 times
Here it is as a function:
func mostFrequent(array: [Int]) -> (value: Int, count: Int)? {
var counts = [Int: Int]()
array.forEach { counts[$0] = (counts[$0] ?? 0) + 1 }
if let (value, count) = counts.max(by: {$0.1 < $1.1}) {
return (value, count)
}
// array was empty
return nil
}
if let result = mostFrequent(array: [1, 3, 2, 1, 1, 4, 5]) {
print("\(result.value) occurs \(result.count) times")
}
1 occurs 3 times
Update for Swift 4:
Swift 4 introduces reduce(into:_:)
and default values for array look ups which enable you to generate the frequencies in one efficient line. And we might as well make it generic and have it work for any type that is Hashable
:
func mostFrequent<T: Hashable>(array: [T]) -> (value: T, count: Int)? {
let counts = array.reduce(into: [:]) { $0[$1, default: 0] += 1 }
if let (value, count) = counts.max(by: { $0.1 < $1.1 }) {
return (value, count)
}
// array was empty
return nil
}
if let result = mostFrequent(array: ["a", "b", "a", "c", "a", "b"]) {
print("\(result.value) occurs \(result.count) times")
}
a occurs 3 times
You can also use the NSCountedSet
, here's the code
let nums = [4, 4, 4, 3, 3, 3, 4, 6, 6, 5, 5, 2]
let countedSet = NSCountedSet(array: nums)
let mostFrequent = countedSet.max { countedSet.count(for: $0) < countedSet.count(for: $1) }
Thanks to @Ben Morrow for the smart suggestions in the comments below.