Getting Started With the Swift Collections Package

Learn about three new data structures available in the Swift Collections package: Deque, OrderedSet and OrderedDictionary. By Felipe Laso-Marsetti.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Ordered Set vs. Set

Note: Here’s a fun, behind-the-scenes fact: OrderedSet stores its values in a regular Swift Array.

Next, you’ll learn about the third new data structure in Swift Collections: OrderedDictionary.

Introducing OrderedDictionary

Your third new data structure friend is OrderedDictionary, which is to Dictionary what OrderedSet is to Set.

Like the regular Dictionary, OrderedDictionary works by using hash tables to ensure that two elements don’t share the same key. The advantage of OrderedDictionary, however, is that it keeps the elements in an order that you specify.

The iPhone preorder system from the OrderedSet section is also a good example of how an OrderedDictionary is useful.

In that system, you used OrderedSet to keep track of the order in which customers placed the preorders as well as which customer placed the order. Its limitation is that the only information associated with a customer is the name you stored in the ordered set.

With OrderedDictionary, you can keep track of your customers and the order in which the preorders were placed — stored as keys in the ordered dictionary. You can also have values for the order details for each customer.

A regular Swift Dictionary offers uniqueness for each customer, but doesn’t guarantee the order of the elements.

Ordered Dictionary vs. Dictionary

Working With OrderedDictionary

Open the OrderedDictionary playground page and scroll to the bottom. Add the following code to create your very own OrderedDictionary:

var orderedDictionary = OrderedDictionary<String, String>()

This creates an empty, mutable OrderedDictionary containing keys and values of type String.

Note: The keys in an OrderedDictionary can be of any type that conform to Hashable. The values can be anything you like!

Next, add the code below to populate your ordered dictionary with some elements:

orderedDictionary["Order 1"] = "Ray"
orderedDictionary["Order 2"] = "James"
orderedDictionary["Order 3"] = "Andrea"
orderedDictionary["Order 4"] = "Elena"
orderedDictionary

Hmmm. This looks similar, if not identical, to working with a regular Dictionary, right? Not quite. Find the line commented // Check the order of the output and look at the values exported from the regular dictionary. You’ll see the elements in a random order, completely different from the order in which you added them to the dictionary. The output of orderedDictionary will always be the same.

Note: You might just see the elements from the standard dictionary in the correct order. That’s just as likely as any other order! Run your code a few times and see how the results are different each time.

With an ordered dictionary, you are guaranteed that the keys and elements are in a consistent order. Add the following code to your playground:

orderedDictionary.keys
orderedDictionary.values.elements

Check the sidebar’s keys and elements after adding this code to verify their order.

If the order of keys and values is guaranteed, that means you can refer to items in the dictionary using indices. You’ll learn about that next.

Swapping Elements Using OrderedDictionary

Because OrderedDictionary maintains the elements’ order, you can use swapAt(_:_:), which allows you to exchange the position of two elements. With this, you don’t need to remove the elements and manually reinsert them in the correct location.

To see how you can swap elements, add the code below to your playground:

orderedDictionary.swapAt(1, 3)

Before, your elements were in the following order:

[
  "Order 1": "Ray", 
  "Order 2": "James", 
  "Order 3": "Andrea", 
  "Order 4": "Elena"
]

Now, they’re like this:

[
  "Order 1": "Ray",
  "Order 4": "Elena",
  "Order 3": "Andrea",
  "Order 2": "James"
]

Just as before, you can check your playground’s sidebar to see these elements.

You learned that ordered sets have different definitions of equality to sets. The same applies to ordered dictionaries and dictionaries.

Checking Equality With OrderedDictionary

As with OrderedSet, two ordered dictionaries must have the same elements in the same order to be considered equal.

Add the code below to check your dictionary’s equality against a second OrderedDictionary:

var secondDictionary = OrderedDictionary<String, String>()
secondDictionary["Order 1"] = "Ray"
secondDictionary["Order 2"] = "James"
secondDictionary["Order 3"] = "Andrea"
secondDictionary["Order 4"] = "Elena"
secondDictionary
orderedDictionary == secondDictionary

You’ll see they aren’t equal. Why? Because you swapped elements earlier. To fix this inequality, add the code below to the end of the file:

secondDictionary.swapAt(1, 3)
orderedDictionary == secondDictionary

The code above swaps the position of the two named elements. Now, the two dictionaries are equal.

Subscripting for OrderedDictionary

As with a regular Swift Dictionary, you can look up, add and remove values via subscripting. Add the following code to try it out:

orderedDictionary["Order 2"] = "Mary"
orderedDictionary

Here, you use subscripting to add the string Mary to your ordered dictionary for the key Order 2.

Make one last comparison between your two OrderedDictionaries to see if they’re equal:

orderedDictionary == secondDictionary

Because you’ve used subscripting to assign order 2 to Mary, the two dictionaries are no longer equal. Thus, the code above returns false.

One final thing that becomes relevant when you have a collection in a specified order is sorting.

Sorting an Ordered Dictionary

If the keys to your dictionary are Comparable, OrderedDictionary gives you access to another useful tool: sort(). As the name implies, it will sort your dictionary by comparing the keys. To see sorting in action, add the following snippet of code at the bottom of your playground:

orderedDictionary.sort()

The dictionary will now be sorted by key value:

[
  "Order 1": "Ray", 
  "Order 2": "Mary", 
  "Order 3": "Andrea", 
  "Order 4": "Elena"
]

To sort by the values instead of the keys, add the following code:

orderedDictionary.sort {
  $0.value < $1.value
}

Now the dictionary is ordered by value:

[
  "Order 3": "Andrea", 
  "Order 4": "Elena",
  "Order 2": "Mary",
  "Order 1": "Ray"
]

Ray is now at the back of the queue for a new iPhone!

You now know the basics about working with OrderedDictionary. But, there's an alternative you might not have heard of which could do the job for you, without having to include use the Collections package.

Understanding KeyValuePairs

In the OrderedDictionary playground page, you'll notice a section called KeyValuePairs.

As the name implies, KeyValuePairs is an ordered collection of key-value pairs. This collection is built-in as part of the Swift language; it's not part of the Swift Collections package. It acts like Dictionary but doesn't have fast key lookup.

There are three main advantages of KeyValuePairs:

  • It's built in.
  • It allows you to store an ordered collection of key-value pairs.
  • Keys don't need to conform to Hashable protocol.

This data structure provides you with more flexibility, but searching for a value is slower because it must search through every element before returning a match. If you're dealing with a small collection of data and conforming to Hashable for the key types is an issue for you, it could be worth considering KeyValuePairs.