Difference between compactMap and flatMap in Swift

Mar 04, 2024#swift#comparison

In Swift, the map(), compactMap(), and flatMap() methods are powerful higher-order functions that operate on sequences, providing concise and expressive ways to transform and manipulate data.

  • Use map() for simple transformations.
  • Use compactMap() to transform and filter out optionals.
  • Use flatMap() to transform and flatten results.

These methods are particularly useful when working with arrays and optionals, allowing you to apply transformations to elements while handling potential nil values efficiently.

Using map() method

The map() method applies a given closure to each element in a sequence (e.g., an array) and returns a new array containing the results of the transformation. It is a versatile tool for creating a one-to-one mapping between the elements of the original sequence and their transformed counterparts.

let numbers = [1, 2, 3, 4]
let doubledNumbers = numbers.map { $0 * 2 } // [2, 4, 6, 8]

Using compactMap() method

The compactMap() method extends the functionality of map() by not only applying a closure to each element but also filtering out any resulting nil values. It is particularly useful when working with optionals, as it simplifies the process of extracting non-nil values from a sequence of optionals.

let optionalNumbers: [Int?] = [1, nil, 3, nil, 5]
let nonNilNumbers = optionalNumbers.compactMap { $0 } // [1, 3, 5]

Using flatMap() method

The flatMap() method goes a step further by not only transforming elements but also flattening nested sequences, such as arrays of arrays or optionals within optionals. It is a versatile tool for handling nested structures and producing a single, unwrapped result.

let nestedStrings: [[String]] = [["apple", "banana"], ["cherry"]]
let allStrings = nestedStrings.flatMap { $0 } // ["apple", "banana", "cherry"]

Remember flatMap() only flattens one level of nested arrays. This means it can combine elements from one level of nested arrays into a single-level array, but it doesn’t handle deeper nesting levels. For scenarios requiring deeper flattening, you can combine flatMap() with other methods like nested flatMap() calls or recursive approaches.