Swift provides two collection types to store collections, arrays, and dictionaries. An array is a collection of serialized lists of the same type. A dictionary is a non-serialized set that can use a unique identifier similar to a key to get values.
In Swift, both the keys and values of the array and the dictionary must be explicit about its type. This means that the array and dictionary do not insert a value of the wrong type, causing an error. This also means that you can determine its type when you retrieve a value in the array and dictionary.
Swift uses a certain collection type to ensure that the code works without errors and allows you to catch errors earlier in the development stage.
note:
Swift's arrays storing different types will show different behaviors, such as variables, constants, or functions and methods. For more information, see Mutability of Collections and Assignment and Copy Behavior for Collection Types.
1. Array
An array is a serialized list that stores different values of the same type. The same value can appear multiple times in different positions in the array.
Swift arrays store determined values, and there is a difference between NSArray and NSMutableArray classes in Objective-C. Because they store various objects and do not provide any specific information about the object. In Swift, whether it is a definite declaration or an implicit declaration, an array is very sure what type it stores itself, and it does not necessarily require that it store a class object. So Swift arrays are type-safe because it always determines the values it can contain.
Abbreviated syntax for arrays
The complete way to define an array is Array<SomeType>. Where SomeType is the type you want to include. You can also use a simple syntax like SomeType[]. Although both methods are functionally the same. But we recommend the latter, and it will be throughout this book.
Array Literals
You can initialize an array with an array of real numbers (Array Literals), which is abbreviated to create an array containing one or more values. An array of real quantities (Array Literals) is composed of the value it contains, the "," separator. The bracket pair "[]" that already includes the above content:
[value 1, value 2, value 3]
The following example creates an array called shoppinglist, which stores a type of string.
var shoppingList: String[] = ["Eggs", "Milk"]
// Use two initialization parameters to initialize shoppingList
The shoppinglist variable is defined as an array of type String (String), written as String[]. Because this array is determined to be a String type, it can only store values of String type. Here, the shoppingList array is initialized by writing two string types values ("Eggs" and "Milk") and array reals (Array Literals).
Notice
The shoppingList array is defined as a variable (using a var identifier) rather than a constant (using a let identifier), so in the following example, you can add elements directly.
In this example, the array real amount (Array Literals) contains only two string type values, which conforms to the definition of the shoppingList variable (only contains arrays of string type (String) type), so the allocated array real amount (Array Literals) is allowed to be initialized with two string type values.
Thanks to Swift's type inference, you can not specify the type when you initialize with the same type of value. The following method can be used instead to initialize shoppingList.
var shoppingList = ["Eggs", “Milk"]
Because all values in the array real amount (Array Literals) are of the same type, Swift can infer that the type of shoppingList is a string array (String[]).
Read and modify arrays
You can read and modify arrays through methods and properties, or subscripts.
Read the length of the array through the read-only property count;
println("The shopping list contains \() items.")
// prints "The shopping list contains 2 items.”
Check whether the length of the array is 0 by a isEmpty property that returns a boolean type
if { println("The shopping list is empty.")
} else { println("The shopping list is not empty.")
}
// prints "The shopping list is not empty."
Adding an element at the end of the array can be done by append method
("Flour")
// shoppingList now contains 3 elements
Even, you can use the (+=) operator to add an element to the end of the array
shoppingList += "Baking Powder"
// shoppingList now contains 4 elements
You can also use the (+=) operator to add an array to the end of another array
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList now contains 7 elements
Take a value from the array using the subscript syntax. If you know the index value of an element, you can fill in the index value in the brackets after the array name to get the element
var firstItem = shoppingList[0]
// firstItem equals "Eggs"
Note that the index value of the first element of the array is 0, not 1, and the Swift array always indexes 0;
You can use the subscript syntax to modify existing values through indexing.
shoppingList[0] = "Six eggs"
//The first value in the list is equal to "Six eggs" and not equal to "Eggs"
You can use the subscript syntax to change a series of values at once, although the modified area is much larger than the value to be modified. In the following thunder, replace "Chocolate Spread", "Cheese", "Butter", "Bananas", "Apples":
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 elements
Note that you cannot add an element to the array using the subscript syntax. If you try to use the subscript syntax to get or set an element, you will get a runtime error. Nevertheless, you can verify that the index is correct and then use it through the count property. When count is 0 (meaning the array is empty), count-1 is out of the valid range of the index, because the index of the array always starts from 0.
Insert a value at a specific index position, you can use the insert(atIndex:) method
("Maple Syrup", atIndex: 0)
// shoppingList now contains 7 elements
// "Maple Syrup" is in the first place in the array
Here, the insert method is called to indicate that a new element is inserted in the location where the index of the shoppingList is 0.
Similarly, you can call the removeAtIndex method to remove specific elements. This method removes an element at a specific index position and has returned the removed element (although you don't care about this return value).
let mapleSyrup = (0)
// Elements with index position 0 are removed
// shoppingList now contains 6 elements, excluding Maple Syrup
// The mapleSyrup constant is equal to the removed "Maple Syrup" string
When the element is removed, the empty position of the array will be filled, so now the element with index position 0 is once again equal to "Six eggs":
firstItem = shoppingList[0]
// firstItem is now equal to "Six eggs"
If you remove the last element from the array, using the removeLast method is more convenient than removingAtIndex, because the latter requires calculating the length of the array through the count property. Like the removeAtIndex method, removeLast returns the removed element.
let apples = ()
//The last element of the element is removed
// shoppingList now contains 5 elements, excluding cheese
// The apples constant is now equal to the removed "Apples" string
Iterate through the array
You can use a for-in loop to iterate through the values in the array
for item in shoppingList { println(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
If you need the shaping index value of each element, it will be more convenient to use the enumerate function instead. The enumerate function returns a tuple containing the index and value of the element for each element. You can break down the ancestors in the traversal and store them in temporary variables or constants.
for (index, value) in enumerate(shoppingList) { println("Item \(index + 1): \(value)")
}
// Element 1: Six eggs
// Element 2: Milk
// Element 3: Flour
// Element 4: Baking Powder
// Element 5: Bananas
For more for-in loop information, see For Loops.
Create and initialize arrays
Create an empty array and use the initialization syntax for the determined type (not including initialization values):
var someInts = Int[]()
println("someInts is of type Int[] with \() items.")
// prints "someInts is of type Int[] with 0 items.”
Note that the someInt variable is determined as Int[] because it uses the initialization method that generates Int[].
Alternatively, if the context already provides type information, such as function parameters or constants and variables of the type that have been determined, you can create an empty array from the empty array real (Array Literals), write [] (empty bracket pairs).
(3)
// someInts now contains 1 Int-type element
someInts = []
// someInts is now an empty array, but the type is still Int[];
Swift array types also provide initialization methods to create arrays that determine length and provide default values. You can add a new array through this initialization method, and the number of elements becomes count, and the appropriate default value is repeatedValue
var threeDoubles = Double[](count: 3, repeatedValue: 0.0)
// The type of threeDoubles is Double[], and equals [0.0, 0.0, 0.0]
Thanks to type inference, you do not need to specify the type stored in this array to use this initialization method, because it can be inferred from the default values.
var anotherThreeDoubles = Array(count: 3, repeatedValue: 2.5)
// anotherThreeDoubles is inferred as Double[], and equals [2.5, 2.5, 2.5]
Finally, you can use the (+) operator to create a new array and add two existing arrays.
This new array type is inferred from the two arrays you added
var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles is inferred as Double[], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
2. Dictionary
A dictionary is a container that stores the same type but different values. Each value corresponds to this unique key, just as every value in the dictionary has an identifier. There is a difference between elements in an array, and elements in a dictionary have no special sequences. When you need to find batch values based on identifiers, you can use a dictionary. Similarly, real item dictionaries are often used as identifiers for finding specific dictionaries.
Swift dictionary stores specific keys and values of a type, and Objective-C's NSDictionary and NSMutableDictionary are distinguished by certain differences because they use various objects as their keys and values, and do not provide any specific information about the object. In Swift, for a specific dictionary, the keys and values it can store are definite, whether it is an explicitly declared type or an implicitly inferred type.
Swift's dictionary is written as Dictionary<KeyType,ValueType>. KeyType is the key you want to store, and ValueType is the value you want to store.
The only limitation is that KeyTypes must be hashable - it is to provide a form that allows them to be independently identified. All basic types of Swift (such as String, Int, Double and Bool) are hashable by default, and these types are often used as keys for dictionaries. Enumerated member values do not require assisted values (specifically described in Enumerations) because they are also hashable by default.
Dictionary Literals
You can directly initialize a dictionary with a dictionary real (Dictionary Literals). The same syntax as the previous definition of an array of real quantities (Array Literals). Dictionary Literals is to use abbreviated writing method to directly write one or more key-value pairs to define a dictionary.
A key-value pair is a combination of keys and values. In Dictionary Literals, each key-value pair is always divided by a colon. The key-value pair is written as a list, divided by commas, and included in a pair of brackets []:
[key 1: value 1, key 2: value 2, key 3: value 3]
In the following example, a dictionary will be created to store the names of international airports. In this dictionary, the key is the three-character International Air Transport Association code, and its value is the name of the airport:
var airport :Dictionary<String, String> = ["TYO": "Tokyo", "DUB": “Dublin"]
The airport dictionary is defined as a type Dictionary<String, String>, which means that the key type of this dictionary is a string String, and its value type is also a String.
Notice
The airport dictionary is defined as a variable (using a var identifier) rather than a constant (using a let identifier), so in the following example, you can add elements directly.
The airport dictionary is initialized using a dictionary real amount (Dictionary Literals) containing two key-value pairs. The first pair consists of a key called "TYO" and a value called "Tokyo", and the second pair has a key called "DUB" and a value called "Dublin".
This dictionary Literals contains two strings: string pairs. This conforms to the type defined by the airport variable (a dictionary only includes the String key and the String value), so it is allowed as two initialization elements of the airport dictionary when assigning the dictionary reals.
Like arrays, if you use the same type when initializing a dictionary, you can not specify the type of the dictionary.
The airport initialization can be replaced by the following abbreviation:
var airports = ["TYO": "Tokyo", "DUB": “Dublin”]
Because all keys are literally the same type, and likewise all values are the same type, Swift can infer that Dictionary<String, String> is the correct type of the airports dictionary.
Read and modify dictionary
You can read and modify dictionaries through attributes, methods, or subscripts. Like arrays, you use the read-only count attribute to check how many elements the dictionary contains.
println("The dictionary of airports contains \() items.")
// prints "The dictionary of airports contains 2 items."
You can add an element to a dictionary using the subscript syntax. Use the appropriate type as the new key and assign it a suitable value
airports["LHR"] = "London"
// airports dictionary now has 3 items
You can also use the subscript syntax to change the value associated with a specific key.
airports["LHR"] = "London Heathrow"
//The value of "LHR" has been changed to "London Heathrow"
Similarly, use the updateValue(forKey:) method of the dictionary to set or update the value of a specific key. Like the above subscript example, the updateValue(forKey:) method will set its value if the key does not exist, and if the key exists, its value will be updated. The updateValue(forKey:) method will return the original old value if it is updated. This enables you to use this to determine whether an update has occurred.
The updateValue(forKey:) method returns an optional value of the same type as the dictionary's value. For example, if the dictionary's value is of type, it returns a String? or "optional String". This optional value contains an old value that is updated if the value is updated and a nil value that does not exist.
if let oldValue = ("Dublin International", forKey: "DUB") {
println("The old value for DUB was \(oldValue).")
}
// prints "The old value for DUB was Dublin."
You can also use the subscript syntax to read a value through a specific key. Because if his value does not exist, his key can be returned, the dictionary subscript syntax will return an optional value of the type of the dictionary value. If the key in the dictionary contains the corresponding value, the dictionary subscript syntax will return the corresponding value of the key, otherwise it will return nil
if let airportName = airports["DUB"] {
println("The name of the airport is \(airportName).")
} else {
println("That airport is not in the airports dictionary.")
}
// prints "The name of the airport is Dublin International."
You can use the subscript syntax to assign its value to nil to remove this key-value pair.
airports["APL"] = "Apple International"
// "Apple International" is not the real airport of APL, so delete it
airports["APL"] = nil
// APL has been removed from the dictionary
Similarly, removing a key-value pair from a dictionary can use the removeValueForKey method. If there is a value corresponding to the key, it removes a key-value pair and returns the removed value, otherwise it returns nil.
if let removedValue = ("DUB") {
println("The removed airport's name is \(removedValue).")
} else {
println("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin International."
Traversal dictionary
You can use a for-in loop to iterate over the dictionary's key-value pairs. Each element in the dictionary returns a tuple, which you can decompose in the loop and store with temporary variables or constants.
for (airportCode, airportName) in airports {
println("\(airportCode): \(airportName)")
}
// TYO: Tokyo
// LHR: London Heathrow
For more information about for-in loops, see For Loops.
You can also read the keys attribute or values attribute of the dictionary to iterate over the collection of keys or values of this dictionary.
for airportCode in {
println("Airport code: \(airportCode)")
}
// Airport code: TYO
// Airport code: LHR
for airportName in {
println("Airport name: \(airportName)")
}
// Airport name: Tokyo
// Airport name: London Heathrow
If you need an interface to create an array instance of a dictionary key or value, you can use the keys or values attributes to initialize a numeric value.
let airportCodes = Array()
// airportCodes is ["TYO", "LHR"]
let airportNames = Array()
// airportNames is ["Tokyo", "London Heathrow"]
Notice
The dictionary type in Swift is a non-serialized collection. If you need to serialize and retrieve keys, values, or key-value pairs, iterating through the dictionary will not be described in detail.
Create an empty dictionary
Like dictionaries, you can create an empty dictionary using the syntax of the determined type.
var namesOfIntegers = Dictionary<Int, String>()
// namesOfIntegers is an empty dictionary of type Dictionary<Int, String>
This example creates an Int, String dictionary to store integer values with better readability. Its keys are of type Int, and their values are of type String.
If type information is already provided in the context, an empty dictionary can be created by a dictionary real (Dictionary Literal), written [;] (including a colon by a pair of []:)
namesOfIntegers[16] = "sixteen"
// namesOfIntegers now contains 1 key-value pair
namesOfIntegers = [:]
// namesOfIntegers is an empty dictionary of type Int, String.
Notice
In this scenario, Swift arrays and dictionary types are a built-in collection. For more built-in types and collections, see Generics
3. Variable collection type
Both arrays and dictionaries store different variables together in a collection. If you create an array or dictionary and then include a variable, the variable you created is called mutable. This means that you can add more elements after creation to change the length of the collection, or remove the ones that have been included. Conversely, if you define an array or dictionary as a constant, the array or dictionary is not mutable and their length cannot be changed.
In a dictionary, immutability also means that you cannot replace the value of an already existing key. An immutable dictionary that cannot be changed once it is set.
The immutability of arrays is a little different. However, you still cannot do anything that has the potential to modify immutable arrays. But you can reset an already existing index, which allows better optimization of array performance when the Swift array length is determined.
Arrays with mutable behavior also affect the allocation and modification of array instances. For more information, see Assignment and Copy Behavior for Collection Types.
Notice
In all examples, it's a good exercise to create immutable sets when the length of the array does not need to be changed.
I'm sure the Swift compiler can optimize the collection you create.