compactMapValues() in Swift 5
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 elements2. 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.