8 New Ways to Refactor Your Code With Swift 4

Optimizing Swift 4

Swift is one of the fastest-growing languages in history, due to its elegance, simplicity, and “safety by design”. In fact, Swift’s official mantra is “to make programming simple things easy, and difficult things possible”. In this post, you’ll learn how to use Swift to its fullest by refactoring your code.

While a lot of the code optimization is implicit and obviously inherent in the language’s design, there are certain refactoring strategies that can make your code more readable, more reliable, and better performing. In this article, you will learn eight ways to refactor your code with Swift 4. 

Objectives of This Article 

In this article, you will learn some ways to better optimize and refactor your code with Swift 4. We’ll cover the following:

  1. handling duplicate keys in dictionaries elegantly with zip
  2. setting default values for dictionaries
  3. merging dictionaries into one
  4. filtering data dictionary values directly into another dictionary object
  5. using Codable to save custom objects into JSON
  6. swapping values in mutable arrays
  7. handling multi-line literals
  8. finding random elements in a collection

1. Duplicate Keys in Dictionaries

First up, Swift 4 further enhances dictionaries with an elegant way to handle duplicate keys using the generic function zip.  zip works on more than just dictionaries, and in fact it will let you build own sequence type from two underlying collections that conform to Sequence. 

For example, say you have an array with the following values, taking note of two elements containing the same key:

By using  zip, you are able to create a sequence of unique pairs:

The uniquingKeysWith elements in the code above allow you to create unique values through the use of a mathematical operator. In this case, we use + to increment the value whenever a duplicate entry is found. Of course, you can also decide to employ your own custom increment logic.

2. Default Values for Dictionaries 

Another powerful feature in Swift 4 is in the ability to set default values for dictionaries, using a newly added subscript. In the following code, when you access the value of a key in the dictionary, the value returned is an optional value, which will return nil if the key doesn’t exist:

Normally you should handle the possibility of nil in optional values, but Swift 4 makes it a bit more convenient for you, through a new subscript which allows you to add default parameters, rather than forcing you to guard or unwrap optionals.

In this case, since we don’t have an entry for New York in our initial array, it will return the default parameter of 0. You can also inject a dynamic value as opposed to a static literal value if you need to, which certainly makes for a much more powerful subscript feature. 

3. Merging Dictionaries

Swift 4 also makes it easier to merge two dictionaries into one through the use of merge(_:uniquingKeysWith:). In the following example, we are merging the second dictionary into the first, and through the use of the newly learned parameter uniquingKeysWith, we can ensure any duplicates will be handled should they occur:

In the absence of this function, you would normally have to manually traverse all the values of a dictionary and implement custom logic in merging two dictionaries into one. 

4. Filtering Dictionary Values Into Another Dictionary

In addition to merging two dictionaries, you can also dynamically filter a dictionary with the results directed back into another dictionary of the same type. In this next snippet of code, we filter the dictionary of locations by a specific value, returned as a dictionary:

So, beyond simple filtering, you can also make use of the filter closure to provide custom filters that will culminate in a new dictionary result. 

5. Save Custom Objects to JSON

If you’ve ever serialized (and deserialized) data before, it can be quite involved, having to subclass classes with NSObject, as well as implementing NSCoding. With Swift 4, you can more efficiently serialize your classes through the use of Codable. This is especially useful when you want to persist by serializing a custom object of yours into a JSON object, either to pass to an API or even to persist locally using UserDefaults:

As you can see, by setting your class or struct to Codable, you can easily serialize your data to JSON, persist the data somewhere, and deserialize back. 

6. Swapping Values in Mutable Arrays

Switching over to arrays, another welcome feature in Swift 4 is the ability to swap two values directly in mutable arrays, by using swapAt(_:_:). This would be most useful for functions such as sorting algorithms, and it’s extremely straightforward to use:

Previously, you would have had to make use of temporary variables to swap between two element locations, but with this method, you can more concisely sort your arrays.

7. Handling Multi-Line Literals

Another cool addition to Swift 4 is the ability to store multiple-line string literals in your values, making it extremely easy to break out your literal content to be more presentable. Through the use of the notation """ to open and close the text block, you can create multi-line content and even reference dynamic variables, as shown below when we dynamically add a date.

8. Picking Random Elements in a Collection

New in Swift 4.2 is the ability to pick random elements in a collection with the randomElement function. In fact, not just arrays but any object that conforms to the Collection protocol can make use of this nifty function. The following example uses our location array, and it will print out a random city from that array:

Conclusion

In this article, you learned some useful techniques that Swift 4 brings to help create more compact, focused, and optimized code. In its fourth iteration, Swift has certainly made strides in helping you refactor your code to be more readable and reliable. Swift 4.x isn’t done yet, and I encourage you to follow the official Swift evolution page to take note of all the new proposals in the pipeline to be discussed.