iOS
Swift
Array Manipulation
Programming
Code Tutorial

iOS Swift remove elements of an array from another array

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Swift, removing all elements from one array that also appear in another array is usually a filtering problem. The best implementation depends on whether the array is small and simple or large enough that repeated membership checks should be optimized.

The Readable Solution: filter

If you want a new array that excludes elements found in another array, filter is the clearest tool.

swift
1let original = [1, 2, 3, 4, 5, 6]
2let toRemove = [2, 4, 6]
3
4let result = original.filter { !toRemove.contains($0) }
5print(result)   // [1, 3, 5]

This is easy to read, but contains on an array is a linear search. For every element in original, Swift may scan much of toRemove.

Use a Set for Faster Membership Checks

When the arrays are larger, convert the removal list to a Set so membership testing becomes much cheaper.

swift
1let original = [1, 2, 3, 4, 5, 6]
2let toRemove = Set([2, 4, 6])
3
4let result = original.filter { !toRemove.contains($0) }
5print(result)   // [1, 3, 5]

This is the usual performance-oriented answer because the overall shape stays simple while the lookup cost improves.

Modifying the Array In Place

If you want to mutate the existing array rather than create a new one, use removeAll(where:).

swift
1var numbers = [1, 2, 3, 4, 5, 6]
2let blocked = Set([2, 4, 6])
3
4numbers.removeAll { blocked.contains($0) }
5print(numbers)  // [1, 3, 5]

This avoids reassigning to a second variable and communicates the intent clearly.

What If Duplicates Matter?

The examples above remove every matching occurrence. That is usually what people want.

For example, if original is [1, 2, 2, 3] and toRemove contains 2, both 2 values are removed. If you instead need multiset behavior, such as removing only one occurrence for each matching element in the second array, you need a counting-based solution rather than a plain membership test.

The Generic Pattern

This works for any Hashable element type, not just integers.

swift
1func removingAll<T: Hashable>(_ source: [T], matching banned: [T]) -> [T] {
2    let bannedSet = Set(banned)
3    return source.filter { !bannedSet.contains($0) }
4}
5
6let names = removingAll(["Ana", "Ben", "Cia"], matching: ["Ben"])
7print(names)

Using a generic helper makes the rule reusable across the codebase.

Choosing Between New Array and Mutation

The API choice is also a readability choice. If callers expect the original array to remain available, returning a filtered copy is clearer. If the array is local state owned by the current scope, removeAll(where:) communicates in-place cleanup directly.

That distinction matters in UI code and data pipelines because mutation can be efficient but also easier to misuse when the same collection is shared across several layers of logic.

Common Pitfalls

  • Using contains on an array inside filter for very large inputs when a Set would be faster.
  • Forgetting that the simple membership approach removes all matching duplicates, not just one occurrence.
  • Mutating an array in place when the caller actually expects the original array to remain unchanged.
  • Converting to a Set when you need to preserve duplicate counts from the removal array.
  • Writing manual loops for a problem that filter and removeAll(where:) already express clearly.

Summary

  • Use filter when you want a new array without matching elements.
  • Convert the removal list to a Set for faster membership checks.
  • Use removeAll(where:) when you want to mutate the original array.
  • The simple approach removes every matching occurrence.
  • Choose between readability and specialized counting logic based on whether duplicate semantics matter.

Course illustration
Course illustration

All Rights Reserved.