compactMapValues() in Swift 5

Eric Giannini
2 min readFeb 24, 2019

--

With the introduction of SE-0218 into Swift 5, compactMapValues() comes as a new method for dictionaries, bridging the gap separating the latter from arrays. Arrays, for instance, operate on its elements through calls to compactMap(), compactMapValues()’s namesake, to transform values, unwrapping their results but at the same time eliminating anything nil.

What is compactMap()?

1. let numbers = ["1", "2", "three", "///4///", "5"]
// an array of String typed elements
2. let mappedNumbers: [Int?] = numbers.map { Int($0) }
// map the String typed elements of the numbers array by Int()
// [1, 2, nil, nil, 5]
3. compactedMappedNumbers: [Int] = numbers.compactMap { Int($0) }
// compactMap the String typed elements of the numbers array by Int()
// [1, 2, 5]

The minimal difference of 2 to 3 is that in 3 the nil values are eliminated. Wheras map() returns an array containing the nil results of calling the given transformation with each element of the sequence, compactMap() does not. While Swift 4 introduces a mapValues() method, mapValues(), however, does not eleminate anything nil. Swift’s mapValues() returns a new dictionary containing the keys of this dictionary with the values transformed by the given closure but does not anything transformed intonil. Accordingly, developers sought to introduce a function for dictionaries called compactMapValues()that is comparable to compactMap() for arrays.

How does compactMapValues() work?

Swift’s compactMapValues() returns a new dictionary containing only the key-value pairs that have non-nil values as the result of transformation by the given closure so the elements of compactMapValues() are the following: 1) a dictionary, 2) the method call, 3) the transform, and 4) the closure.

let data = ["a":"1", "b":"three", "c":"///4//"]let compactMapValues: [String: Int] = data.compactMapValues { Int($0) }
// ["a": 1]

Our dictionary is data. Our method call compactMapValues() is called on data. The transform is Int(). The closure encapsulates the transform. It is really straightforward.

Optionals

Swift’s compactMapValues() is useful for unwrapping optionals. Whilst the common methods of forced unwrapping, implicitingly unwrapping, nil coalescing, optional binding / chaining, unwrapping options with compactMapValues() is another way that is safe, since keys without any values do not crash a program.

--

--

Eric Giannini
Eric Giannini

Written by Eric Giannini

🙌 Working with Swift, Kotlin, the world wide web

Responses (1)