Working with Array and Dictionary Collections in Swift

Arrays and dictionaries in Swift are objects that contain collections of other objects. This chapter will cover some of the basics of working with arrays and dictionaries in Swift.

Mutable and Immutable Collections

Collections in Swift come in mutable and immutable forms. The contents of immutable collection instances cannot be changed after the object has been initialized. To make a collection immutable, assign it to a constant when it is created. On the other hand, collections are mutable if assigned to a variable.

Swift Array Initialization

An array is a data type designed specifically to hold multiple values in a single ordered collection. An array, for example, could be created to store a list of String values. Strictly speaking, a single Swift based array is only able to store values that are of the same type. An array declared as containing String values, therefore, could not also contain an Int value. As will be demonstrated later in this chapter, however, it is also possible to create mixed type arrays. The type of an array can be specified specifically using type annotation or left to the compiler to identify using type inference.

An array may be initialized with a collection of values (referred to as an array literal) at creation time using the following syntax:

var variableName: [type] = [value 1, value2, value3, ……. ]Code language: plaintext (plaintext)

The following code creates a new array assigned to a variable (thereby making it mutable) that is initialized with three string values:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

var treeArray = ["Pine", "Oak", "Yew"]Code language: Swift (swift)

Alternatively, the same array could have been created immutably by assigning it to a constant:

let treeArray = ["Pine", "Oak", "Yew"]Code language: Swift (swift)

In the above instance, the Swift compiler will use type inference to decide that the array contains values of String type and prevent values of other types being inserted into the array elsewhere within the application code. Alternatively, the same array could have been declared using type annotation:

var treeArray: [String] = ["Pine", "Oak", "Yew"]Code language: Swift (swift)

Arrays do not have to have values assigned at creation time. The following syntax can be used to create an empty array:

var variableName = [type]()Code language: Swift (swift)

Consider, for example, the following code which creates an empty array designated to store floating point values and assigns it to a variable named priceArray:

var priceArray = [Float]()Code language: Swift (swift)

Another useful initialization technique allows an array to be initialized to a certain size with each array element pre-set with a specified default value:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

var nameArray = [String](repeating: "My String", count: 10)Code language: Swift (swift)

When compiled and executed, the above code will create a new 10 element array with each element initialized with a string that reads “My String”.

Finally, a new array may be created by adding together two existing arrays (assuming both arrays contain values of the same type). For example:

let firstArray = ["Red", "Green", "Blue"]
let secondArray = ["Indigo", "Violet"]
 
let thirdArray = firstArray + secondArrayCode language: Swift (swift)

Working with Arrays in Swift

Once an array exists, a wide range of methods and properties are provided for working with and manipulating the array content from within Swift code, a subset of which is as follows:

Array Item Count

A count of the items in an array can be obtained by accessing the array’s count property:

var treeArray = ["Pine", "Oak", "Yew"]
var itemCount = treeArray.count
 
print(itemCount)Code language: Swift (swift)

Whether or not an array is empty can be identified using the array’s Boolean isEmpty property as follows:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

var treeArray = ["Pine", "Oak", "Yew"]
 
if treeArray.isEmpty {
    // Array is empty
}Code language: Swift (swift)

Accessing Array Items

A specific item in an array may be accessed or modified by referencing the item’s position in the array index (where the first item in the array has index position 0) using a technique referred to as index subscripting. In the following code fragment, the string value contained at index position 2 in the array (in this case the string value “Yew”) is output by the print call:

var treeArray = ["Pine", "Oak", "Yew"]
 
print(treeArray[2])Code language: Swift (swift)

This approach can also be used to replace the value at an index location:

treeArray[1] = "Redwood"Code language: Swift (swift)

The above code replaces the current value at index position 1 with a new String value that reads “Redwood”.

Random Items and Shuffling

A call to the shuffled() method of an array object will return a new version of the array with the item ordering randomly shuffled, for example:

let shuffledTrees = treeArray.shuffled()Code language: Swift (swift)

To access an array item at random, simply make a call to the randomElement() method:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

let randomTree = treeArray.randomElement()Code language: Swift (swift)

Appending Items to an Array

Items may be added to an array using either the append method or + and += operators. The following, for example, are all valid techniques for appending items to an array:

treeArray.append("Redwood")
treeArray += ["Redwood"]
treeArray += ["Redwood", "Maple", "Birch"]Code language: Swift (swift)

Inserting and Deleting Array Items

New items may be inserted into an array by specifying the index location of the new item in a call to the array’s insert(at:) method. An insertion preserves all existing elements in the array, essentially moving them to the right to accommodate the newly inserted item:

treeArray.insert("Maple", at: 0)Code language: Swift (swift)

Similarly, an item at a specific array index position may be removed using the remove(at:) method call:

treeArray.remove(at: 2)Code language: Swift (swift)

To remove the last item in an array, simply make a call to the array’s removeLast method as follows:

treeArray.removeLast()Code language: Swift (swift)

Array Iteration

The easiest way to iterate through the items in an array is to make use of the for-in looping syntax. The following code, for example, iterates through all of the items in a String array and outputs each item to the console panel:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

let treeArray = ["Pine", "Oak", "Yew", "Maple", "Birch", "Myrtle"]
 
for tree in treeArray {
    print(tree)
}Code language: Swift (swift)

Upon execution, the following output will appear in the console:

Pine
Oak
Yew
Maple
Birch
MyrtleCode language: plaintext (plaintext)

The same result can be achieved by calling the forEach() array method. When this method is called on an array, it will iterate through each element and execute specified code. For example:

treeArray.forEach { tree in
    print(tree)
}Code language: Swift (swift)

Note that since the task to be performed for each array element is declared in a closure expression, the above example may be modified as follows to take advantage of shorthand argument names:

treeArray.forEach {
    print($0)
}Code language: Swift (swift)

Creating Mixed Type Arrays

A mixed type array is an array that can contain elements of different class types. Clearly, an array that is either declared or inferred as being of type String cannot subsequently be used to contain non-String class object instances. Interesting possibilities arise, however, when taking into consideration that Swift includes the Any type. Any is a special type in Swift that can be used to reference an object of a non-specific class type. It follows, therefore, that an array declared as containing Any object types can be used to store elements of mixed types. The following code, for example, declares and initializes an array containing a mixture of String, Int and Double elements:

let mixedArray: [Any] = ["A String", 432, 34.989]Code language: Swift (swift)

The use of the Any type should be used with care since the use of Any masks from Swift the true type of the elements in such an array thereby leaving code prone to potential programmer error. It will often be necessary, for example, to manually cast the elements in an Any array to the correct type before working with them in code. Performing the incorrect cast for a specific element in the array will most likely cause the code to compile without error but crash at runtime. Consider, for the sake of an example, the following mixed type array:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

let mixedArray: [Any] = [1, 2, 45, "Hello"]Code language: Swift (swift)

Assume that, having initialized the array, we now need to iterate through the integer elements in the array and multiply them by 10. The code to achieve this might read as follows:

for object in mixedArray {
    print(object * 10)
}Code language: Swift (swift)

When entered into Xcode, however, the above code will trigger a syntax error indicating that it is not possible to multiply operands of type Any and Int. In order to remove this error it will be necessary to downcast the array element to be of type Int:

for object in mixedArray {
    print(object as! Int * 10)
}Code language: Swift (swift)

The above code will compile without error and work as expected until the final String element in the array is reached at which point the code will crash with the following error:

Could not cast value of type ‘Swift.String’ to ‘Swift.Int’Code language: plaintext (plaintext)

The code will, therefore, need to be modified to be aware of the specific type of each element in the array. Clearly, there are both benefits and risks to using Any arrays in Swift.

Swift Dictionary Collections

String dictionaries allow data to be stored and managed in the form of key-value pairs. Dictionaries fulfill a similar purpose to arrays, except each item stored in the dictionary has associated with it a unique key (to be precise, the key is unique to the particular dictionary object) which can be used to reference and access the corresponding value. Currently only String, Int, Double and Bool data types are suitable for use as keys within a Swift dictionary.

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

Swift Dictionary Initialization

A dictionary is a data type designed specifically to hold multiple values in a single unordered collection. Each item in a dictionary consists of a key and an associated value. The data types of the key and value elements type may be specified specifically using type annotation, or left to the compiler to identify using type inference.

A new dictionary may be initialized with a collection of values (referred to as a dictionary literal) at creation time using the following syntax:

var variableName: [key type: value type] = [key 1: value 1, key 2: value2 …. ]Code language: Swift (swift)

The following code creates a new dictionary assigned to a variable (thereby making it mutable) that is initialized with four key-value pairs in the form of ISBN numbers acting as keys for corresponding book titles:

var bookDict = ["100-432112" : "Wind in the Willows",
                "200-532874" : "Tale of Two Cities",
                "202-546549" : "Sense and Sensibility",
                "104-109834" : "Shutter Island"]Code language: Swift (swift)

In the above instance, the Swift compiler will use type inference to decide that both the key and value elements of the dictionary are of String type and prevent values or keys of other types being inserted into the dictionary. Alternatively, the same dictionary could have been declared using type annotation:

var bookDict: [String: String] = 
               ["100-432112" : "Wind in the Willows",
                "200-532874" : "Tale of Two Cities",
                "202-546549" : "Sense and Sensibility",
                "104-109834" : "Shutter Island"]Code language: Swift (swift)

As with arrays, it is also possible to create an empty dictionary, the syntax for which reads as follows:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

var variableName = [key type: value type]()Code language: Swift (swift)

The following code creates an empty dictionary designated to store integer keys and string values:

var myDictionary = [Int: String]()Code language: Swift (swift)

Sequence-based Dictionary Initialization

Dictionaries may also be initialized using sequences to represent the keys and values. This is achieved using the Swift zip() function, passing through the keys and corresponding values. In the following example, a dictionary is created using two arrays:

let keys = ["100-432112", "200-532874", "202-546549", "104-109834"]
let values = ["Wind in the Willows", "Tale of Two Cities", 
                "Sense and Sensibility", "Shutter Island"]
 
let bookDict = Dictionary(uniqueKeysWithValues: zip(keys, values))Code language: Swift (swift)

This approach allows keys and values to be generated programmatically. In the following example, a number range starting at 1 is being specified for the keys instead of using an array of predefined keys:

let values = ["Wind in the Willows", "Tale of Two Cities", 
               "Sense and Sensibility", "Shutter Island"]
 
var bookDict = Dictionary(uniqueKeysWithValues: zip(1..., values))Code language: Swift (swift)

The above code is a much cleaner equivalent to the following dictionary declaration:

var bookDict = [1 : "Wind in the Willows",
                2 : "Tale of Two Cities",
                3 : "Sense and Sensibility",
                4 : "Shutter Island"]Code language: Swift (swift)

Dictionary Item Count

A count of the items in a dictionary can be obtained by accessing the dictionary’s count property:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

print(bookDict.count)Code language: Swift (swift)

Accessing and Updating Dictionary Items

A specific value may be accessed or modified using key subscript syntax to reference the corresponding value. The following code references a key known to be in the bookDict dictionary and outputs the associated value (in this case the book entitled “A Tale of Two Cities”):

print(bookDict["200-532874"])Code language: Swift (swift)

When accessing dictionary entries in this way, it is also possible to declare a default value to be used in the event that the specified key does not return a value:

print(bookDict["999-546547", default: "Book not found"])Code language: Swift (swift)

Since the dictionary does not contain an entry for the specified key, the above code will output text which reads “Book not found”.

Indexing by key may also be used when updating the value associated with a specified key, for example, to change the title of the same book from “A Tale of Two Cities” to “Sense and Sensibility”):

bookDict["200-532874"] = "Sense and Sensibility"Code language: Swift (swift)

The same result is also possible by making a call to the updateValue(forKey:) method, passing through the key corresponding to the value to be changed:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

bookDict.updateValue("The Ruins", forKey: "200-532874")Code language: Swift (swift)

Adding and Removing Dictionary Entries

Items may be added to a dictionary using the following key subscripting syntax:

dictionaryVariable[key] = valueCode language: Swift (swift)

For example, to add a new key-value pair entry to the books dictionary:

bookDict["300-898871"] = "The Overlook"Code language: Swift (swift)

Removal of a key-value pair from a dictionary may be achieved either by assigning a nil value to the entry, or via a call to the removeValueForKey method of the dictionary instance. Both code lines below achieve the same result of removing the specified entry from the books dictionary:

bookDict["300-898871"] = nil
bookDict.removeValue(forKey: "300-898871")Code language: Swift (swift)

Dictionary Iteration

As with arrays, it is possible to iterate through dictionary entries by making use of the for-in looping syntax. The following code, for example, iterates through all of the entries in the books dictionary, outputting both the key and value for each entry:

for (bookid, title) in bookDict {
  print("Book ID: \(bookid) Title: \(title)")
}Code language: Swift (swift)

Upon execution, the following output will appear in the console:

 

 

You are reading a sample chapter from iOS 17 App Development Essentials.

Buy the full book now in eBook (PDF and ePub) or Print format.

The full book contains 68 chapters, over 580 pages of in-depth information, and downloadable source code.

Learn more.

Preview  Buy eBook  Buy Print

 

Book ID: 100-432112 Title: Wind in the Willows
Book ID: 200-532874 Title: The Ruins
Book ID: 104-109834 Title: Shutter Island
Book ID: 202-546549 Title: Sense and SensibilityCode language: plaintext (plaintext)

Summary

Collections in Swift take the form of either dictionaries or arrays. Both provide a way to collect together multiple items within a single object. Arrays provide a way to store an ordered collection of items where those items are accessed by an index value corresponding to the item position in the array. Dictionaries provide a platform for storing key-value pairs, where the key is used to gain access to the stored value. Iteration through the elements of Swift collections can be achieved using the for-in loop construct.


Categories