What is compactMapValues { $0 } ?

compactMapValues {} can be really helps when we are dealing with optional values inside a dictionary. Readability is also important, especially amongs the developers. compactMapValues is one of the great language feature of Swift.

“Returns a new dictionary containing only the key-value pairs that have non-nil values as the result of transformation by the given closure.” – Apple Documentation

syntax of compact map is Dictionary.compactMapValues { $0 }.

Why we need it & How to use it?

Supposed that we need to send a JSON body to our server when the user updates any of his / her changed Information and the server don’t want to receive any nil values. We can generate the dictionary manually using manual assignment and if let checking for available values like the code below.

case .updateProfile(let firstName, let lastName, let phoneNumber, let photo):
            
            var  params: [String: Any] = [:]
            
            if let firstName = firstName {
                params["first_name"] = firstName
            }
            if let lastName = lastName {
                params["last_name"] = lastName
            }
            if let phoneNumber = phoneNumber {
                params["phone_number"] = phoneNumber
            }
            if let photo = photo {
                params["photo"] = photo
            }

						return params

in this case, if there is no nil values on each parameters, when we will get JSON like this :

{
	"first_name": "Arifin", 
	"last_name": "Firdaus",
	"phone_number": "081123123123"
	"photo": "<https://arifinfrds.com/sample-image.png>"
}

Dictionary.compactMapValues { $0 } to the rescue!

We can achieve the same JSON with Dictionary.compactMapValues { $0 }. In this case, we don’t even need each of if let statement, making the code is more elegant and clean. Like the code below :

case .updateProfile(let firstName, let lastName, let phoneNumber, let photo):
            
            var  params: [String: Any] = [:]
						params["first_name"] = firstName
						params["last_name"] = lastName
						params["phone_number"] = phoneNumber
						params["photo"] = photo

						return params.compactMapValues { $0 }

In the code above, first we assigned any values to corresponding keys. Supposed that we have a nil value on one of the variables, then before .compactMapValues {} , the JSON will be like this :

{
	"first_name": "Arifin", 
	"last_name": "Firdaus",
	"phone_number": nil
	"photo": "<https://arifinfrds.com/sample-image.png>"
}

And of course, we don’t want this. The server or the backend guy also don’t want this. So, with compactMapValues {} , the nil values is automatically excluded from the dictionary, and of course the JSON. The result will be like this below :

{
	"first_name": "Arifin", 
	"last_name": "Firdaus",
	"photo": "<https://arifinfrds.com/sample-image.png>"
}

Conclusion

Dictionary.compactMapValues { $0 } can really helps the developers to get rid of bloated code when dealing with optional keys inside the dictionary. With this, the syntax becomes more readable, easy to understand, and simple.

Reference(s)

CompactMapValues(_:) https://developer.apple.com/documentation/swift/dictionary/3081323-compactmapvalues

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s