CompactMap helps you clean up a list by removing empty or missing values. It unwraps optionals safely and keeps only real values.
You have a list with some missing or empty values and want only the real ones.
You want to convert a list of strings to numbers, ignoring the ones that can't be converted.
You want to filter out nil values from a list of optional items.
You want to clean user input data by removing blanks or invalid entries.
Syntax
Swift
let newArray = oldArray.compactMap { item in// return a non-optional value or nil
}
The closure inside compactMap must return an optional value.
compactMap removes all nil results and unwraps the rest.
Examples
This converts strings to integers, ignoring "three" which can't be converted.
Swift
let strings = ["1", "2", "three", "4"]
let numbers = strings.compactMap { Int($0) }
print(numbers)
This removes nil values from a list of optional integers.
Swift
let optionalInts: [Int?] = [1, nil, 3, nil, 5]
let ints = optionalInts.compactMap { $0 }
print(ints)
Sample Program
This program takes a list of strings, tries to convert each to an integer, and keeps only the valid numbers.
Swift
let mixedStrings = ["10", "abc", "20", "", "30"]
let validNumbers = mixedStrings.compactMap { str inInt(str)
}
print("Valid numbers:", validNumbers)
OutputSuccess
Important Notes
compactMap is great for safely unwrapping optionals while filtering out nils.
It is different from map because map keeps nils as optionals, compactMap removes them.
Summary
compactMap unwraps optionals and removes nil values from collections.
Use it to clean lists by keeping only real, non-nil values.
It helps avoid crashes from forced unwrapping of nil optionals.
Practice
(1/5)
1. What does the compactMap function do when used on an array of optionals in Swift?
easy
A. It unwraps optionals and removes all nil values from the array.
B. It converts all values to strings regardless of their type.
C. It sorts the array in ascending order.
D. It replaces all nil values with zero.
Solution
Step 1: Understand what compactMap does
compactMap takes an array of optionals and unwraps each element, removing any nil values.
Step 2: Compare with other options
It does not convert types, sort, or replace nil with zero. It only filters out nil and unwraps values.
Final Answer:
It unwraps optionals and removes all nil values from the array. -> Option A
Quick Check:
compactMap removes nil = B [OK]
Hint: Remember: compactMap unwraps and drops nils [OK]
Common Mistakes:
Confusing compactMap with map (which keeps nils)
Thinking compactMap sorts or changes types
Assuming compactMap replaces nil with default values
2. Which of the following is the correct syntax to use compactMap on an array numbers of type [Int?] to get an array of non-optional Int values?
easy
A. let result = numbers.compactMap { $0 }
B. let result = numbers.compactMap { Int($0) }
C. let result = numbers.compactMap { $0! }
D. let result = numbers.compactMap { String($0) }
Solution
Step 1: Understand the input and output types
numbers is an array of optional integers [Int?]. We want to unwrap and remove nil values to get [Int].
Step 2: Check each option's correctness
let result = numbers.compactMap { $0 } uses compactMap { $0 } which unwraps optionals and removes nil. let result = numbers.compactMap { Int($0) } tries to convert optional Int to Int again, which is unnecessary. let result = numbers.compactMap { $0! } force unwraps, which can crash if nil. let result = numbers.compactMap { String($0) } converts to String, changing type.
Final Answer:
let result = numbers.compactMap { $0 } -> Option A
Quick Check:
Use compactMap with identity closure to unwrap optionals [OK]
Hint: Use compactMap { $0 } to unwrap optionals safely [OK]
Common Mistakes:
Using force unwrap inside compactMap causing runtime errors
Trying to convert optionals unnecessarily
Changing the type unintentionally
3. What is the output of the following Swift code?
let values: [Int?] = [1, nil, 3, nil, 5]
let unwrapped = values.compactMap { $0 }
print(unwrapped)
medium
A. Compilation error
B. [1, 3, 5]
C. [1, nil, 3, nil, 5]
D. [Optional(1), Optional(3), Optional(5)]
Solution
Step 1: Understand the input array
The array values contains optional integers with some nil values.
Step 2: Apply compactMap
compactMap { $0 } unwraps optionals and removes nil values, resulting in [1, 3, 5].
Final Answer:
[1, 3, 5] -> Option B
Quick Check:
compactMap removes nils and unwraps = [1, 3, 5] [OK]
Hint: compactMap removes nils and unwraps optionals [OK]
Common Mistakes:
Expecting optionals in output instead of unwrapped values
Thinking nils remain in the output
Confusing compactMap with map
4. Identify the error in this Swift code snippet and choose the correct fix:
let strings: [String?] = ["apple", nil, "banana"]
let lengths = strings.compactMap { $0.count }
print(lengths)
medium
A. Error: Use force unwrap $0! before accessing count
B. Error: compactMap should be replaced with map
C. No error; code runs correctly
D. Error: Cannot use $0.count on optional; fix by using compactMap { $0?.count }
Solution
Step 1: Analyze the closure inside compactMap
The closure uses $0.count, but $0 is an optional String?. Accessing count directly on optional causes error.
Step 2: Correct the closure to safely unwrap
Using $0?.count returns an optional Int, which compactMap unwraps and removes nils, fixing the error.
Final Answer:
Error: Cannot use $0.count on optional; fix by using compactMap { $0?.count } -> Option D
Quick Check:
Use optional chaining inside compactMap closure [OK]
Hint: Use optional chaining ($0?.property) inside compactMap [OK]
Common Mistakes:
Trying to access property directly on optional causing error
Using map instead of compactMap losing nil filtering
Force unwrapping causing runtime crashes
5. Given a dictionary [String: Int?] representing item stock counts, how can you create a new dictionary with only items that have a non-nil stock count using compactMap or similar methods?
hard
A. Use filter { $0.value != nil } without unwrapping values.
B. Use mapValues { $0! } to force unwrap all values.
C. Use compactMapValues { $0 } to unwrap and filter out nil values.
D. Use compactMap { $0 } directly on the dictionary.
Solution
Step 1: Understand dictionary optional values
The dictionary has optional Int values. We want to remove keys with nil values and unwrap the rest.
Step 2: Use compactMapValues to unwrap and filter
compactMapValues { $0 } unwraps optionals in values and removes entries with nil values, producing a dictionary with non-optional Int values.
Final Answer:
Use compactMapValues { $0 } to unwrap and filter out nil values. -> Option C
Quick Check:
compactMapValues unwraps and filters dictionary values [OK]
Hint: Use compactMapValues to unwrap and remove nil dictionary values [OK]
Common Mistakes:
Using mapValues with force unwrap risking crashes
Filtering without unwrapping values
Trying to use compactMap directly on dictionary
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.