Swift
Array
Grouping
Programming
Tutorial

How to group by the elements of an array in Swift

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Grouping is a common operation when you want to turn a flat array into buckets. In Swift, the cleanest solution is usually Dictionary(grouping:by:), which builds a dictionary whose keys represent groups and whose values are arrays containing the matching elements.

Group Values with Dictionary(grouping:by:)

Swift gives you a purpose-built initializer for grouping collections. It walks the array once, applies a closure to each element, and stores the element under the returned key.

Here is the simplest example, grouping numbers by parity:

swift
1let numbers = [1, 2, 3, 4, 5, 6]
2
3let grouped = Dictionary(grouping: numbers) { number in
4    number % 2 == 0 ? "even" : "odd"
5}
6
7print(grouped["even"] ?? [])
8print(grouped["odd"] ?? [])

The resulting dictionary maps "even" to [2, 4, 6] and "odd" to [1, 3, 5]. This is usually what people mean by "group an array."

The grouping key can be any Hashable type. Strings are common, but enums, integers, and custom hashable structs also work well.

Group Structs by One of Their Properties

Grouping becomes more useful with custom models. Suppose you have products and want to group them by category:

swift
1struct Product {
2    let name: String
3    let category: String
4}
5
6let products = [
7    Product(name: "Keyboard", category: "Hardware"),
8    Product(name: "Mouse", category: "Hardware"),
9    Product(name: "Pages", category: "Software"),
10    Product(name: "Numbers", category: "Software")
11]
12
13let groupedByCategory = Dictionary(grouping: products, by: \.category)
14
15for (category, items) in groupedByCategory {
16    print(category, items.map(\.name))
17}

Using a key path keeps the code short and expressive. This is especially helpful when the grouping rule is simply "use this property as the bucket."

A useful mental model is:

  • the closure decides the bucket name
  • Swift appends each element to the correct array
  • the final result is a dictionary of grouped arrays

Group by a Computed Rule

You are not limited to stored properties. The closure can return any derived key. For example, you can group strings by their first letter:

swift
1let names = ["Alice", "Aaron", "Bob", "Bella", "Chris"]
2
3let groupedByFirstLetter = Dictionary(grouping: names) { name in
4    String(name.prefix(1))
5}
6
7print(groupedByFirstLetter["A"] ?? [])
8print(groupedByFirstLetter["B"] ?? [])

This pattern is powerful because it lets you group by ranges, dates, prefixes, status values, or anything else that can be computed from the element.

You can also post-process the grouped values. For example, if you only need counts:

swift
let counts = groupedByFirstLetter.mapValues(\.count)
print(counts)

That converts grouped arrays into a compact summary without repeating the grouping logic.

When Order Matters

One detail matters in Swift: the arrays inside each group keep the original order of matching elements, but the dictionary itself does not promise a meaningful sorted order for keys. If you need stable output for display, sort the keys before iterating.

swift
for key in groupedByFirstLetter.keys.sorted() {
    print(key, groupedByFirstLetter[key] ?? [])
}

This is often the difference between correct data and user-friendly presentation.

Common Pitfalls

The first common issue is expecting an array instead of a dictionary. Grouping produces [Key: [Element]], not [[Element]]. If you need only the grouped arrays, you can use Array(grouped.values), but you lose the labels that explain what each group means.

Another mistake is forgetting that keys must be Hashable. If you try to group by a custom type that does not conform to Hashable, the code will not compile. In that case, group by a hashable property or add the conformance explicitly.

Optional data can also create awkward groups. If an element may not have a category, decide whether to group it under a label such as "Unknown" or to filter it out before grouping.

Finally, do not rely on the dictionary's iteration order. If display order matters, sort the keys or convert the grouped result into a sorted array of pairs before using it in the UI.

Summary

  • Use Dictionary(grouping:by:) to group an array into buckets efficiently.
  • The result type is a dictionary whose values are arrays of matching elements.
  • Grouping can use a property, a key path, or any computed rule.
  • Elements keep their original order inside each group.
  • Sort keys explicitly when you need predictable output order.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.