Swift 3: getting the most frequent array value

I have an array of numbers, and I want to know which number is most often found in this array. An array sometimes has 5-6 integers, sometimes it has 10-12, and sometimes more - integers in an array can be different. Therefore, I need a function that can work with different lengths and values ​​of the array.

One example:

myArray = [0, 0, 0, 1, 1] 

Another example:

 myArray = [4, 4, 4, 3, 3, 3, 4, 6, 6, 5, 5, 2] 

Now I am looking for a function that returns 0 (in the first example) as Integer , since it has 3 times in this array, and the other integer in the array (1) is only 2 times in the array, Or for the second example it will be 4.

It seems pretty simple, but I can't find a solution for this. Found some examples on the Internet where the solution should work with dictionaries or where the solution is simple - but I can not use it with Swift 3, it seems ...

However, I did not find a solution that works for me. Does anyone have an idea how to get the most frequent integer in an array of integers?

Thanks guys.

+4
source share
3 answers
 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(isOrderedBefore:) if let (value, count) = counts.max(isOrderedBefore: {$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(isOrderedBefore: {$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 
+13
source

You can also use NSCountedSet , here is 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.

+15
source

The most common value is called "mode". Here's the short version:

 let mode = myArray.reduce([Int: Int]()) { var counts = $0 counts[$1] = ($0[$1] ?? 0) + 1 return counts }.max { $0.1 < $1.1 }?.0 

No matter what is considered “unreadable” or “graceful”, it depends on your feelings for higher-order functions. However, here it is a generic method in extending to Array (so it will work with any type of Hashable element):

 extension Array where Element: Hashable { var mode: Element? { return self.reduce([Element: Int]()) { var counts = $0 counts[$1] = ($0[$1] ?? 0) + 1 return counts }.max { $0.1 < $1.1 }?.0 } } 

Just remove .0 if you prefer a tuple that includes a mode counter.

+6
source

Source: https://habr.com/ru/post/1014370/


All Articles