Swift
String Manipulation
Array
Programming
Swift Tutorial

Split a String into 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

Splitting a string is a common task in Swift, whether you are parsing CSV-like input, breaking a sentence into words, or handling user-entered commands. The main thing to remember is that Swift offers more than one API here, and the best choice depends on whether you need characters, substrings, empty fields, or Foundation conveniences.

The Basic Tool: split(separator:)

For most cases, Swift’s built-in split method is the right starting point. It returns an array of Substring values.

swift
1let text = "apple,banana,cherry"
2let parts = text.split(separator: ",")
3
4print(parts)
5print(type(of: parts[0]))

This produces an array containing three pieces. The important detail is the return type. Swift uses Substring for efficiency so it can reference slices of the original string without copying immediately.

If you actually need [String], convert the result explicitly:

swift
1let text = "apple,banana,cherry"
2let strings = text
3    .split(separator: ",")
4    .map(String.init)
5
6print(strings)

That conversion is common when the pieces will outlive the original string or when an API specifically expects String.

Controlling Empty Pieces and Split Count

By default, split omits empty subsequences. That is convenient for ordinary word splitting, but it can be wrong for data formats where empty fields matter.

swift
1let row = "A,,C,"
2
3let defaultSplit = row.split(separator: ",")
4print(defaultSplit)
5
6let keepEmpty = row.split(
7    separator: ",",
8    omittingEmptySubsequences: false
9)
10print(keepEmpty)

With default behavior, the empty fields disappear. With omittingEmptySubsequences: false, Swift preserves them, which is much safer for record parsing.

You can also limit the number of splits:

swift
1let command = "deploy:production:version-42"
2let pieces = command.split(separator: ":", maxSplits: 1)
3
4print(pieces)

That is useful when you want the first separator to divide the string and leave the remainder intact.

When components(separatedBy:) Is Better

Swift’s split works with separators at the character level. If you already use Foundation and want a [String] result directly, components(separatedBy:) can be simpler.

swift
1import Foundation
2
3let text = "red--green--blue"
4let colors = text.components(separatedBy: "--")
5
6print(colors)

This is especially handy when:

  • the separator is a string instead of one character
  • you want [String] right away
  • you are already using Foundation APIs elsewhere

It also works with character sets:

swift
1import Foundation
2
3let sentence = "one,two;three four"
4let words = sentence.components(separatedBy: .punctuationCharacters)
5
6print(words)

That said, components(separatedBy:) does not automatically make the code better. For simple single-character splits, split is often clearer and more Swifty.

Practical Parsing Patterns

Suppose you receive a line of user input where the first word is a command and the rest is a message. split(maxSplits:) is a clean fit:

swift
1let input = "say Hello from Swift"
2let parts = input.split(separator: " ", maxSplits: 1)
3
4let command = parts.first.map(String.init) ?? ""
5let message = parts.count > 1 ? String(parts[1]) : ""
6
7print(command)
8print(message)

For CSV-like rows, preserving empties usually matters more:

swift
1let csv = "alice,29,,toronto"
2let fields = csv.split(
3    separator: ",",
4    omittingEmptySubsequences: false
5).map(String.init)
6
7print(fields)

That gives you the missing third field instead of silently removing it.

Performance and Lifetime Notes

Because split returns Substring, it can be efficient for temporary parsing. But Substring keeps storage tied to the original string. If you keep many small substrings around after the source text should go away, you can accidentally retain more memory than expected.

That is why converting to String is not just about type compatibility. It is also a lifecycle decision. Use Substring briefly for local parsing, then convert when you need independent values.

Common Pitfalls

The most common pitfall is forgetting that split returns [Substring], not [String]. That becomes visible when passing the result to APIs that require String.

Another mistake is relying on the default omission of empty fields when parsing structured data. For CSV-like text, that can shift columns and corrupt meaning.

A third issue is using components(separatedBy:) for every case out of habit. It works, but for simple character separators the built-in split API is often more direct.

Finally, developers sometimes assume multiple-character separators work exactly like character separators everywhere. Check which API you are using and what it expects.

Summary

  • Use split(separator:) for most Swift string-splitting tasks.
  • Remember that split returns [Substring], which you can convert with .map(String.init).
  • Set omittingEmptySubsequences: false when empty fields are meaningful.
  • Use maxSplits when you want only the first few separators to count.
  • Reach for components(separatedBy:) when Foundation-based string splitting is a better fit.

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.