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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Getting Started With the Swift Collections Package
30 mins
- Getting Started
- Understanding Deque
- Deque vs. Array
- Deque
- Array
- Working With Deque
- Appending and Prepending With Deque
- Removing Items From a Deque
- Comparing the Performance of Deque Versus Array
- Knowing When to Use Deque
- Introducing OrderedSet
- Ordered Set vs. Set
- Set
- Ordered Set
- Working With OrderedSet
- Checking for Equality Using OrderedSet
- Adding Elements to an Existing OrderedSet
- Removing Elements From an OrderedSet
- Knowing When to Use OrderedSet
- Ordered Set vs. Set
- Introducing OrderedDictionary
- Ordered Dictionary vs. Dictionary
- Dictionary
- Ordered Dictionary
- Working With OrderedDictionary
- Swapping Elements Using OrderedDictionary
- Checking Equality With OrderedDictionary
- Subscripting for OrderedDictionary
- Sorting an Ordered Dictionary
- Understanding KeyValuePairs
- Knowing When to Use OrderedDictionary
- Ordered Dictionary vs. Dictionary
- Where to Go From Here?
Comparing the Performance of Deque Versus Array
Using Deque
to add items to the beginning of a large sequence is more performant. To compare the performance of inserting an element at the beginning of an Array
versus a Deque
, add the following code to the playground:
for number in 1...2000 {
array.append("\(number)")
deque.append("\(number)")
}
var start = Date()
array.insert("0", at: 0)
print(Date().timeIntervalSince(start))
start = Date()
deque.prepend("0")
print(Date().timeIntervalSince(start))
This code takes your existing sequences and adds two thousand elements into each. From there, you add an element at the beginning of each sequence and measure the time it takes.
Run your playground a couple of times and pay attention to the results. Notice how Deque
is consistently faster than Array
for this operation.
Knowing When to Use Deque
As you have seen, deques are very similar to arrays. Their main advantage lies in the increased efficiency when adding or removing to the beginning of the collection. However, as you’ve seen, the performance difference may be very small for a lot of cases. The only way to be sure that it’s worth using deques is to run performance testing, using Instruments, on a device. See our Instruments tutorial for more details.
All things considered, it’s great that Deque
and Array
are so similar because it’s quicker for you to learn and use Deque
. You now have the option to use Deque
when you need a more traditional double-ended queue.
In the next section, you’ll learn about a new type where the decision to use it or not is much more obvious.
Introducing OrderedSet
Here’s the major reason to rejoice about the Swift Collections package: OrderedSet
!
Before this, it was frustrating to keep a unique list of items in a specific order in Swift, especially because that’s a common scenario. Think of an app that processes a store’s preorders. There can only be one preorder per customer. If you, Ray and I all want to preorder the next iPhone, Apple needs to know who placed the order first, second and last. While a Swift Array
could work for this, you’d need to write extra code to prevent the user from adding duplicate items to the collection.
Set
, the old alternative to Array
, could maintain each element’s uniqueness, but it doesn’t maintain or guarantee the order. You could use a tuple or custom type to track the position or order, but this would get cumbersome, add extra code to your project and result in reduced performance compared to a proper, native set that maintains order.
Now, there’s a data structure that fills in both of those gaps: OrderedSet
. It not only guarantees the uniqueness of elements, but it also maintains their order!
Ordered Set vs. Set
Working With OrderedSet
Open the Ordered Set page in the playground and add the following code at the very bottom:
var orderedSet = OrderedSet<String>()
Voilà! You’ll see an OrderedSet
of Swift strings. Like other Swift Collections, you can create an ordered set using a literal like this:
var orderedSet: OrderedSet<String> = []
Now, to add items to your ordered set, add the following code to your playground:
orderedSet.append(customer2)
orderedSet.append(customer1)
orderedSet.append(customer3)
orderedSet
As with many other collections in Swift, append(_:)
adds elements to the OrderedSet
. The resulting ordered set looks like this:
["Andrea", "James", "Ray"]
Notice that the ordered set respects the order in which you added the elements.
Checking for Equality Using OrderedSet
With OrderedSet
, checking for equality against another collection works differently than with a regular Set
. Set
checks to ensure that both collections contain the exact same elements regardless of the order, whereas OrderedSet
checks that the elements are the same and appear in the same order.
Add the following code to your playground to test this:
orderedSet == [customer2, customer1, customer3]
Compare that to the example code applied to set
:
set == [customer1, customer2, customer3]
Notice that Set
‘s elements were a different order than the collection you compared, but it still returned true
when checking for equality.
Next, you’ll learn how to add an object to an existing OrderedSet
.
Adding Elements to an Existing OrderedSet
To add an object when working with Set
, you only need to specify an element to add to the collection. But with OrderedSet
, you also need to include an index because it keeps track of the order of elements. To do this, add the following code to your playground:
var result = orderedSet.insert(customer4, at: orderedSet.startIndex)
orderedSet
This is the resulting collection:
["Elena", "Andrea", "James", "Ray"]
This code adds Elena to the beginning of your ordered set.
Next, you’ll learn how to remove an element.
Removing Elements From an OrderedSet
You can also remove elements from an ordered set using remove()
. Add the following code to your playground:
orderedSet.remove(customer1)
orderedSet
Here, you specified the element you want to remove and let OrderedSet
take care of it. You don’t have to worry about figuring out the index of the element you want to remove.
Unlike Set
, OrderedSet
implements most of SetAlgebra
, but not all of it. This can be important should your project require it for backward compatibility with your existing code.
To try using SetAlgebra
with OrderedSet
, add the following code to your playground:
orderedSet.isSubset(of: allCustomers)
The result will be true
, because this method checks to see if OrderedSet
is a subset of allCustomers
, not if the order of the elements is the same.
Knowing When to Use OrderedSet
Use your newfound best friend, OrderedSet
, when you need to maintain both the uniqueness and the order of the elements in your collection. Otherwise, you can continue to use Set
. This is especially true if you:
- Rely on
SetAlgebra
‘s’ operations and compliance - Need to use
elements
to work with existing functions that don’t supportOrderedSet
.
Now, you’ll learn about how OrderedSet
works to further help in your decision-making process.
Equality between two ordered sets happens when both the elements and their order are the same. In contrast, a Set
only needs both sets to contain the same elements to have equality.
At the end of the previous section, you saw that OrderedSet
implements most of SetAlgebra
, but doesn’t conform to it. The documentation for Swift Collections mentions that OrderedSet
is “incompatible with SetAlgebra’s documented semantic requirements” due to the way it checks the order of the elements when it compares for equality.
Operations that return an ordered set will usually take into account the original order of the elements. However, some, like isSubset(of:)
, do not.
If your code needs SetAlgebra
, you could still potentially work with OrderedSet
because it does have an unordered
property that returns an unordered collection of your elements. The unordered collection it returns is of type UnorderedView
.
Now, it’s time to move on to the performance side of OrderedSet
.
As with with Set
, the performance of your code will depend on the quality of hashing that the elements of your OrderedSet
implement. This is great news because you don’t have to pay a performance penalty for using OrderedSet
instead of Set
. This differs from the penalty you pay for using Deque
instead of Array
in scenarios that the latter could handle gracefully.