What is flatMap vs map on Optional? What about Optional.map vs array map?
Predict first
What is the type of a?
let s: String? = "42"
let a = s.map { Int($0) }
print(type(of: a))
- Optional<Int>
- Optional<Optional<Int>>
- Int
Mental model. map wraps whatever you return in another box. flatMap refuses to double-box — it flattens one layer.
Optional.map transforms the wrapped value; the result is still optional. Returns T → result T?.
Optional.flatMap is for closures that already return an optional. It unwraps one extra layer, so U? stays U? instead of becoming U??.
On sequences the names differ: map is 1:1, compactMap drops nils, flatMap concatenates nested sequences. Optional.flatMap and Sequence.flatMap are different functions that happen to share a name.
Int($0) already returns Int?, and map wraps it again. flatMap flattens it back to Int?.
Common traps
- Using
mapwhere the closure returns an optional. You getT??and then need??or a second unwrap — a smell thatflatMapwas wanted. - Thinking
compactMapandflatMapare interchangeable.flatMapon an array of arrays flattens;compactMapremoves nils. Different jobs.
They might follow up with
- Why was
flatMaprenamed tocompactMapfor optionals? Because overloading on “flattening” was ambiguous for sequences of optionals;compactMapmade intent explicit. - What does
try? f().map(g)do? ReturnsU?; iffthrows you get nil, if it succeeds you map the value.
Related questions
- 1.2.6 How does optional chaining (a?.b?.c) actually work?