How to Merge Arrays in Swift? A Complete Breakdown with Examples and Performance Secrets
If you've ever written code in Swift, you've likely faced the task: "I have two arrays, how do I make them into one?" The question seems simple, but behind it lies a whole world of optimizations and nuances. This question has garnered thousands of views on Stack Overflow — and for good reason. Today, we won't just show you how to write the code; we'll look under the hood of the compiler and find out what actually happens when you write array1 + array2. Let's go!
The Most Obvious Way: The + Operator
Let's start with the classic. In Swift, arrays can be added like numbers:
let first = [1, 2, 3]let second = [4, 5, 6]let result = first + secondprint(result) // [1, 2, 3, 4, 5, 6]Elegant? Yes. Fast? Not always. When you use +, Swift creates a new array and copies the elements from both source arrays into it. If your arrays are large (say, 100,000 elements each), that's double the work for the processor. But wait — there's a nuance called copy-on-write (COW).
The Magic of Copy-on-Write: How Swift Saves Memory
Swift is a smart language. When you simply assign one array to another, it doesn't copy the data immediately:
var a = [1, 2, 3]var b = a // As long as the data isn't modified, a and b point to the same memory regionb.append(4) // This is where the actual copy happens: b gets its own copyThis is called copy-on-write. However, when merging with +, this doesn't apply — the result is always a new array. Why? Because we aren't just referencing old data; we are creating a new collection from elements of two different sources. The compiler cannot guarantee that the source arrays won't change, so it makes a full copy.
The append(contentsOf:) Method: When Speed Matters More
If you need to add elements from one array to the end of another without creating a third array, use append(contentsOf:):
var numbers = [1, 2, 3]let moreNumbers = [4, 5, 6]numbers.append(contentsOf: moreNumbers)print(numbers) // [1, 2, 3, 4, 5, 6]In this case, Swift doesn't create a new array — it expands the existing one. If the numbers array has enough reserved memory (capacity), the new elements are simply copied into the free space. If not, memory reallocation occurs, but it's still faster than creating an array from scratch.
Pro tip: If you know you'll be adding many elements, pre-allocate memory using reserveCapacity():
var bigArray: [Int] = []bigArray.reserveCapacity(1000)for i in 0..<1000 { bigArray.append(i) // No unnecessary copying!}The flatMap Method: Merging Arrays with Transformation
Sometimes you need not just to join arrays, but also to transform each element. That's where flatMap (or compactMap for optionals) comes in. Strictly speaking, flatMap is designed for "flattening" collections, but it can also be used for concatenation:
let arrays = [[1, 2], [3, 4], [5, 6]]let flattened = arrays.flatMap { $0 }print(flattened) // [1, 2, 3, 4, 5, 6]Under the hood, flatMap does the same thing as a loop with append(contentsOf:). But the code becomes cleaner and more readable. However, if you just need to join two arrays — don't use flatMap, it's overkill.
reduce(into:) for Flexible Merging
If you have an array of arrays and want to merge them with additional logic, try reduce(into:):
let arrayOfArrays = [[1, 2], [3, 4], [5, 6]]let merged = arrayOfArrays.reduce(into: [Int]()) { r