Collection Data Structures in Swift
Learn about the fundamental collection data structures in this tutorial: arrays, dictionaries and sets. By Niv Yahel.
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
Collection Data Structures in Swift
40 mins
- Getting Started
- What is “Big-O” Notation?
- Common iOS Data Structures
- Arrays
- Expected Performance and When to Use Arrays
- Sample App Testing Results
- Dictionaries
- When to use Dictionaries
- Expected Performance
- Sample App Testing Results
- Sets
- When to use Sets
- Sample App Testing Results
- Lesser-known Foundation Data Structures
- NSCache
- NSCountedSet
- NSOrderedSet
- NSHashTable and NSMapTable
- NSIndexSet
- Pop Quiz!
- Where to Go From Here?
NSIndexSet
An NSIndexSet
is an immutable collection of unique unsigned integers intended to represent indexes of an array.
If you have an NSArray of ten items where you regularly need to access items' specific positions, you can store an NSIndexSet and use NSArray's objectsAtIndexes:
to pull those objects directly:
let items : NSArray = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
let indexSet = NSMutableIndexSet()
indexSet.add(3)
indexSet.add(8)
indexSet.add(9)
items.objects(at: indexSet as IndexSet) // returns ["four", "nine", "ten"]
You specify that "items" is an NSArray
since right now, Swift arrays don't have an equivalent way to access multiple items using an NSIndexSet
or a Swift equivalent.
An NSIndexSet
retains the behavior of NSSet
that only allows a value to appear once. Hence, you shouldn't use it to store an arbitrary list of integers unless only a single appearance is a requirement.
With an NSIndexSet
, you're storing indexes as sorted ranges, so it is more efficient than storing an array of integers.
Pop Quiz!
Now that you've made it this far, you can test your memory with a quick quiz about what sort of structure you might want to use to store various types of data.
For the purposes of this quiz, assume you have an application where you display information in a library.
Q: What would you use to create a list of every author in the library?
[spoiler title="Unique List of Author Names"]
A Set! It automatically removes duplicate names, which means you can enter every single author's name as many times as you want, but you'll still have only a single entry -- unless you mistype an author's name, doh!
Once you create the Set, you can use set.allObjects
to access the Array of unique names, and then perform operations that depend on order such as sorting.
[/spoiler]
Q: How would you store the alphabetically sorted titles of a prolific author's entire body of work?
[spoiler title="Alphabetically-Sorted Titles"]
An Array! Since you're in a situation where you have a number of similar objects (all titles are Strings) and their order matters (titles must be sorted alphabetically) this is an ideal case for an Array.
[/spoiler]
Q: How would you store the most popular book by each author?
[spoiler title="Most Popular Book by each author"]
A Dictionary! If you use the author's name as the key and the title of that author's most popular book as the value, you can access the most popular book by any author like this:
mostPopularBooks["Gillian Flynn"] //Returns "Gone Girl"
[/spoiler]
Where to Go From Here?
I'd like to give special thanks to my fellow tutorial team member, Ellen Shapiro, who initially created this tutorial and updated it until Swift 1.2. I would also like to thank Chris Wagner, who started on an Objective-C version of this article before the SwiftHammer came down upon us all, for passing along his notes and sample project for me to use while pulling this tutorial together.
I'll also say thanks to the Swift team at Apple -- constant improvements to Swift have made the native data structures stay true to the Swift name. In the foreseeable future, it seems that we won't have a need for the Foundation data structures anymore. :]
If you want to learn more about data structures for iOS, here are a few excellent resources:
- NSHipster is a fantastic resource for exploring little-known corners of the Cocoa APIs including data structures.
- Peter Steinberger of PSPDFKit fame's excellent article in ObjC.io issue 7 on Foundation data structures.
- Former UIKit engineer Andy Matuschak's article in ObjC.io issue 16 about Struct-based data structures in Swift.
- AirspeedVelocity, a blog looking into some of the internals of Swift, has written a blog post titled "Arrays, Linked Lists, and Performance". It closely follows implementing a stable merge sort.
- A super, super deep dive into the internals of
NSMutableArray
, and how changing items in anNSMutableArray
affects memory. - A fascinating study of how NSArray and CFArray performance changes with extremely large data sets. This is further evidence that Apple names classes not for what they do under the hood, but how they work for developers.
- If you want to learn more about algorithmic complexity analysis, Introduction to Algorithms will fill your brain with more than you're likely to ever need to know in practice, but perhaps exactly as much as you'll need to know to pass job interviews.
Got more questions? Go nuts in the comments below!