Swift: 4 Ways to Count the Frequency of Array Elements

Updated: May 5, 2023 By: Khue Post a comment

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]