When developing applications with Swift, there might be cases where you need to calculate the frequency distribution of elements in the array (or count the occurrences of elements in an array), such as when finding the most popular items in a shopping cart or seeking for the most common words in a text
This practical, straight-to-the-point article will walk you through some different ways to compute the number of times each element appears in a given array. Without any further ado; let’s get started.
Using the reduce() method
You can use the reduce()
method to create a dictionary that maps each element to its count as shown below:
let x = ["slingacademy.com", "dog", "cat", "book", "dog", "cat", "dog", "slingacademy.com"]
let cnts = x.reduce(into: [:]) {
counts, word in
counts[word, default: 0] += 1
}
print(cnts)
Output:
["cat": 2, "slingacademy.com": 2, "dog": 3, "book": 1]
Using the map() method
You can also use the map()
method to create an array of tuples with each element and the number 1, then use a dictionary initializer to sum up the values for each key. This technique is pretty concise (and cool).
Example:
let items = ["a", "b", "a", "c", "b", "a", "d"]
let mappedItems = items.map { ($0, 1) }
let counts = Dictionary(mappedItems, uniquingKeysWith: +)
print(counts)
Output:
["a": 3, "b": 2, "c": 1, "d": 1]
Using a for loop
In this approach, the result is still stored in a dictionary. You can use a for
loop to iterate over the array and update the dictionary for each element (use the default parameter to assign a default value of 0 for any key that is not in the dictionary).
Example:
let array = [1, 2, 3, 4, 5, 1, 2, 3, 1, 1]
// The dictionary to hold the counts
var counts: [Int: Int] = [:]
for item in array {
// Increment the count for the item
counts[item, default: 0] += 1
}
print(counts)
Output:
[2: 2, 5: 1, 3: 2, 1: 4, 4: 1]
Using the NSCountedSet class
This approach is longer and more verbose than necessary, but it’s good to know an extra solution for the task. You can use the NSCountedSet
class to create a collection that counts the number of times each element appears in an array. Then you can use a for loop to create a dictionary from the counted set by using its allObjects
and count(for:)
methods.
Example:
import Foundation
let array = ["Sling", "Academy", "Swift", "iOS", "Academy", "Sling", "Swift", "Swift", "iOS", "iOS", "iOS"]
// The dictionary to hold the counts
var counts: [String: Int] = [:]
// Create a counted set from the array
let countedSet = NSCountedSet(array: array)
for item in countedSet.allObjects {
if let item = item as? String {
// Get the number of occurrences for the item
let count = countedSet.count(for: item)
// Add the key-value pair to the dictionary
counts[item] = count
}
}
print(counts)
Output:
["iOS": 4, "Swift": 3, "Academy": 2, "Sling": 2]