Swift
array
groupBy
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 an array in Swift usually means building a dictionary where the keys represent categories and the values are arrays of matching elements. Swift has a built-in initializer for this on Dictionary, so you often do not need to write the grouping loop by hand. The important part is choosing the grouping key correctly and understanding that the result is a dictionary, not a new ordered array.

Use Dictionary(grouping:by:)

Swift’s standard library provides the cleanest built-in solution.

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

This produces a dictionary like:

swift
["even": [2, 4, 6], "odd": [1, 3, 5]]

The closure defines the group key for each element.

Grouping Objects by a Property

Grouping becomes especially useful with structs or models.

swift
1struct User {
2    let name: String
3    let team: String
4}
5
6let users = [
7    User(name: "Ava", team: "Platform"),
8    User(name: "Noah", team: "Infra"),
9    User(name: "Mia", team: "Platform")
10]
11
12let byTeam = Dictionary(grouping: users, by: { $0.team })
13
14print(byTeam["Platform"]?.map(\u005c.name) ?? [])

This is the normal way to bucket values by some field in Swift.

Grouping by Derived Keys

The grouping key does not have to be a stored property. It can be something derived.

swift
1let words = ["ant", "apple", "bat", "ball", "cat"]
2
3let byFirstLetter = Dictionary(grouping: words) { word in
4    word.first!
5}
6
7print(byFirstLetter)

This makes the grouping operation flexible and expressive.

What the Result Type Looks Like

The result type is:

swift
[Key: [Element]]

For example:

swift
let grouped: [String: [Int]] = Dictionary(grouping: numbers) {
    $0 % 2 == 0 ? "even" : "odd"
}

That means each key maps to an array of original elements that belong to that group.

Order Considerations

The arrays inside each group preserve the source order of elements. But the dictionary itself does not represent a business-ordering guarantee the way an array does.

If you need sorted group keys, sort them explicitly:

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

This matters when presenting grouped results in a predictable UI.

Manual Grouping Still Has Uses

Sometimes you want more control than Dictionary(grouping:by:) provides, such as custom accumulation or transforming values while grouping.

swift
1var grouped: [String: [String]] = [:]
2
3for user in users {
4    grouped[user.team, default: []].append(user.name.uppercased())
5}
6
7print(grouped)

This manual pattern is still useful when the grouping step and the transformation step need to happen together.

Counting Group Sizes

If you only need counts per group, you can still start from the grouped dictionary:

swift
let counts = byTeam.mapValues { $0.count }
print(counts)

Or accumulate counts directly:

swift
1var counts: [String: Int] = [:]
2for user in users {
3    counts[user.team, default: 0] += 1
4}
5print(counts)

Choose the version that matches whether you need the grouped elements themselves or only summary data.

Grouping Optionals Safely

If the grouping key may be optional, decide how to represent missing values.

swift
1struct Item {
2    let title: String
3    let category: String?
4}
5
6let items = [
7    Item(title: "A", category: "books"),
8    Item(title: "B", category: nil)
9]
10
11let groupedItems = Dictionary(grouping: items) { item in
12    item.category ?? "uncategorized"
13}
14
15print(groupedItems.keys)

Making the fallback explicit keeps the groups easier to reason about.

Common Pitfalls

The biggest mistake is expecting a grouped result to still behave like an ordered list. Another is forgetting that the result values are arrays and not just counts or single items. Developers also sometimes use manual loops for simple grouping when Dictionary(grouping:by:) would be shorter and clearer. Finally, optional grouping keys should be handled deliberately rather than left to accidental nil logic.

Summary

  • Use Dictionary(grouping:by:) for the standard grouping operation in Swift.
  • The result type is a dictionary from grouping key to array of matching elements.
  • Grouping keys can be direct properties or derived values.
  • The grouped arrays preserve source order, but dictionary key iteration order should not be treated as business ordering.
  • Use manual accumulation only when you need custom transformation or counting logic during grouping.

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.