Swift provides two types of collections to hold multiple values-arrays (array) and dictionaries (Dictionary). Arrays store values of the same type in an ordered list. Dictionaries store values of the same type in an unordered collection, which can be referenced and looked up by a unique identifier (that is, the key).
In swift, the types of values that can be stored in arrays and dictionaries are clear. This means that you cannot mistakenly add the value of a wrong type to an array or dictionary, and it means that you know exactly what type of value you get from an array or dictionary. The Swift collection is type-aware, which ensures that your code will clearly know the type of values they can handle and that you will be able to identify any input errors during the code development phase.
Note: Swift's array behaves differently from other types when it assigns a value to a constant, variable, or value to a function or method. For details, see Assignment and copy behavior for variable sets and collection types
Arrays (Array)
An array stores more than one type of value in an ordered list. The same value can appear multiple times in different positions in the array.
The type of Swift's array of values that they can hold is clear. This differs from the Nsarray class and the Nsmutablearray class of Objective-c, where an array of objective-c can store any type of object and does not provide any information about the objects themselves. In Swift, the type of a value that can be stored by any particular array is always determined, either by an explicit type description or by type inference, and the type does not have to be a class type. For example, if you create an array of type int, you cannot insert any value that is not of type int into the array. The swift array is type-safe, and it always knows what values it can store.
Shorthand syntax for array types
The type of the swift array is Array<sometype>, where the SomeType is the type in which an array can be stored. You can also abbreviate the array type to sometype[]. Although the two forms are functionally identical, we prefer to use shorthand, and all of the array types in this book are in shorthand form.
Array literal
You can initialize an array with an array literal, simply by putting one or more values together. The array literal is written as a comma-separated line of values, and the lines are wrapped up in parentheses with one end of each other:
[Value 1, Value 2, value 3]
The following example creates an array that holds a string of type value named Shoppinglist:
- var shoppinglist:string[] = ["Eggs", "Milk"]
- Shoppinglist initialization with two elements
According to string[], the variable shoppinglist is declared as "an array that holds string values." Because this array indicates that the value type is string, it can only hold a value of type string. The shoppinglist array here is initialized with an array literal that contains two elements of type string ("Eggs" and "Milk").
Note: The array shoppinglist is declared as a variable (with the keyword Var) instead of a constant (with the keyword let) because more elements are added to the shopping list in the following example.
In this case, the array literal contains only two string values. This is consistent with the type in the shoppinglist variable definition (an array that holds string values), so you can assign the array literal directly to the shoppinglist for initialization.
Thanks to Swift's type inference, if you use array literals to initialize an array, the values in the array literal have the same type, and you don't have to explicitly write out the type of the array. The code for initializing shoppinglist above can be abbreviated as:
- var shoppinglist = ["Eggs", "Milk"]
Because all values in the array literal have the same type, swift can infer that the type of the shoppinglist variable is string[].
Access and modification of arrays
Access and modification of an array can be done through the methods and properties of the arrays, or by using the array's next-label method.
To know the number of elements in an array, you can view its read-only property count:
- println ("The shopping list contains \ (shoppinglist.count) items.")
- Output "The shopping list contains 2 items."
Using the Boolean IsEmpty property, you can quickly check if the Count property is 0:
- If Shoppinglist.isempty {
- println ("The shopping list is empty.")
- } else {
- println ("The shopping list is not empty.")
- }//Output "The shopping list is not empty."
To add an element to the end of the array, you can call the Append method of the array:
- Shoppinglist.append ("flour")
- Shoppinglist now contains 3 elements, and it looks like someone's going to have a pancake.
Add an element to the end of the array, or you can use the + = operator:
- Shoppinglist + = "Baking Powder"
- Shoppinglist now consists of 4 elements.
You can also use the + = operator to concatenate an array of the same type to the following array:
- Shoppinglist + = ["Chocolate Spread", "Cheese", "Butter"]
- Shoppinglist now consists of 7 elements.
To get a value from an array, you can use the next banner method. In the parentheses immediately following the array name, pass in the index value of the element to be obtained:
- var FirstItem = shoppinglist[0]
- FirstItem equals "Eggs"
Note that the index value of the first element of the array is 0, not 1. The swift array is always indexed starting at 0.
You can use the subscript syntax to change an existing value for a given index:
- Shoppinglist[0] = "Six eggs"
- The first item in this list is now "Six eggs", not "eggs".
You can use the following banner to change the value of a specified range at once, even if the number of elements to be replaced is not the same as the number of elements that will be replaced. The following example replaces "Chocolate Spread", "Cheese" and "Butter" with "Bananas" and "Apples"
- SHOPPINGLIST[4...6] = ["Bananas", "Apples"]//Shoppinglist now contains 6 elements
Note: You cannot add a new element to the end of the array by using the following banner. Attempting to fetch or hold an element using a subscript that exceeds the range of the array results in a run-time error. Before using an index value, it should be compared to the array's Count property to detect if it is valid. Unless count is 0 (meaning that this is an empty array), the maximum valid index of an array is always count-1, since the index of the array starts at 0.
To insert an element into a specific location, you can call the array's insert (Atindex:) Method:
- Shoppinglist.insert ("Maple syrup", atindex:0)
- Shoppinglist now consists of 7 elements
- The first element of the list is now "Maple syrup"
This call to the Insert function adds a new element with a value of "Maple syrup" to the beginning of the shopping list by specifying subscript 0.
Similarly, you can use the Removeatindex method to remove an element from an array. This method deletes the element on the specified index and returns the deleted element (if you do not need a return value, you can ignore it):
- Let Maplesyrup = Shoppinglist.removeatindex (0)
- An element with index 0 has been deleted from the array.
- Shoppinglist now contains 6 elements and does not contain "Maple syrup"
- Constant Maplesyrup is now equal to the deleted string "Maple syrup"
When an element is deleted, there is no space left in the array where there are no elements. So the element at index 0 becomes "Six eggs":
- FirstItem = shoppinglist[0]
- FirstItem now equals "Six eggs."
If you want to delete the last element of an array, you can use the Removelast method instead of using the Removeatindex method, which avoids having to call the array's Count property. Similar to the Removeatindex method, the Removelast method also returns the element that was deleted:
- Let apples = shoppinglist.removelast ()///The last element of the array was deleted//Shoppinglist now contains 5 elements, does not contain "cheese"//constant apples is now equal to the deleted string " Apples "
Iterate access to arrays
You can iterate through the values of the entire array by for-in loops.
- For item in Shoppinglist {
- println (item)
- }
- Six eggs
- Milk
- Flour
- Baking Powder
- Bananas
If you want to get the index of each element and its corresponding value, you can use the global enumerate method to iterate over the array. The enumerate method returns a tuple that consists of index values and corresponding element values for each element. You can convert a member of a tuple into a variable or constant to use:
- For (index, value) in enumerate (shoppinglist) {
- println ("Item \ (index + 1): \ (value)")
- }
- Item 1:six Eggs
- Item 2:milk
- Item 3:flour
- Item 4:baking Powder
- Item 5:bananas
For more information on the for-in cycle, see for Loops.
Array creation and initialization
You can create an empty array of a specific type by initializing the syntax, and the array does not contain any initial values:
- var someints = int[] ()
- println ("someints is of type int[] with \ (someints.count) items.")
- Output "someints is of type int[] with 0 items.
Note that the variable someints is inferred as the int[] type, because it receives the return value of the int[-type initialization function.
Also, if you have provided type information in the context, such as a method parameter, a constant of a defined type, or a variable, you can use an empty array literal to create an empty array. Empty array literals are written as [], which is a pair of square brackets that do not include any content.
- Someints.append (3)
- Someints now contains an integer value of someints = []
- Someints now becomes an empty array, but its type is still int[]
The swift array also provides an initialization function that generates an array of several repeating elements. The number of elements to be added to the new array (count) and an appropriate default value (Repeatedvalue) are passed to the initialization function:
- var threedoubles = double[] (count:3, repeatedvalue:0.0)
- Threedoubles type is double[], value is [0.0, 0.0, 0.0]
Thanks to the type inference of swift, when using this initialization function, it is not necessary to describe exactly the type of the array, as this can be inferred from the default values:
- var anotherthreedoubles = Array (Count:3, repeatedvalue:2.5)
- The type of anotherthreedoubles is inferred as double[], and the value is [2.5, 2.5, 2.5]
Dictionary (Dictionary)
A dictionary is a container that stores the same values for multiple types. Each value corresponds to a unique key, which in the dictionary is the unique identifier of its corresponding value. Unlike arrays, the elements in the dictionary do not have a specific order. Use a key in the dictionary to query its corresponding value in the same way that you use a word to query a word in a "real-world dictionary."
Swift's dictionary is clear about the type of keys and values that they can hold. This differs from Objective-c's Nsdictionary class and Nsmutabledictionary class, and the Objective-c dictionary can store any type of object as a key or value, and does not provide any information about the objects themselves. In swift, any particular dictionary key and value whose type is always determined, either by an explicit type description, or by type inference.
Swift's dictionary type is Dictionary<keytype, Valuetype>, where KeyType is the type of the key in the dictionary, and ValueType is the type of the value in the dictionary.
The only limitation on the key type KeyType is that it must be hashed, that is, it must be able to provide a way for itself to be represented. All of Swift's underlying types, such as String, Int, double, and bool, are hashed by default and can be used as keys in the dictionary. Values that do not have a bound value in an enumeration member (see enumeration) are also hashed by default.
Dictionary literal
You can initialize an array with a dictionary literal, whose syntax is similar to the array literal you saw earlier. The dictionary literal is a simple way to write a dictionary with a single or multiple key-value pairs.
A key-value pair is a combination of a key and a value. In the dictionary literal, the keys and values in each pair of key-value pairs are separated by a colon, and the key-value pairs are separated by commas, and these key-value pairs are wrapped with a pair of parentheses:
[Key 1:value 1, key 2:value 2, key 3:value 3]
The following example creates a dictionary that stores the name of an international airport, in which the key is the three-letter IATA code, and the value is the name of the airport:
- var airports:dictionary<string, string> = ["Tyo": "Tokyo", "DUB": "Dublin"]
Airports is defined as a dictionary<string, string>-type dictionary, that is, "a key is of type string, and the type of value is a dictionary of string."
Note: The dictionary airports is declared as a variable (with the keyword Var) instead of a constant (with the keyword let) because more airports are added to the dictionary in the following example.
Here the dictionary airports uses a dictionary literal to initialize, the dictionary literal contains two key-value pairs, the first pair of keys is "Tyo", the value is "Tokyo", the second pair of the key is "DUB", the value is "Dublin".
In this example, this array literal contains only two string:string key-value pairs. This is consistent with the type in the airports variable definition (the type of the key is string, and the value type is string), so you can assign the dictionary literal directly to the airports for initialization.
Just like an array, if you initialize a dictionary with a dictionary literal that has the corresponding type of key and value, you do not have to explicitly write out the type of the dictionary. The code for initializing airports above can be abbreviated as:
- var airports = ["Tyo": "Tokyo", "DUB": "Dublin"]
Because all keys in this dictionary literal have the same type and all values have the same type, swift can infer that the type of the airports variable is dictionary<string, string>.
Access and modification of dictionaries
Access and modification of dictionaries can be done through dictionary methods and properties, or by using the dictionary's Under-banner method. Just like an array, the number of elements in dictionary can be obtained through the read-only attribute count:
- println ("The Dictionary of Airports contains \ (airports.count) items.")
- Output "The Dictionary of Airports contains 2 items."
You can add new elements to the dictionary by using the following banner. Use a new key of the appropriate type as the subscript index, and assign it a value of the appropriate type:
- airports["LHR"] = "London"
- Dictionary airports now consists of 3 elements
You can also use the subscript syntax to change the value of a key:
- airports["LHR"] = "London Heathrow"
- The value of "LHR" was changed to "London Heathrow
You can also use the Updatevalue (Forkey:) function to override subscripts when setting or updating values for a specific key. As in the example above, the Updatevalue (forkey:) function sets a new value when the key does not exist and updates the value when the key is present. Unlike the following banner method, the Updatevalue (forkey:) function returns the old value after updating a value. This allows you to detect if a value update has occurred.
The Updatevalue (forkey:) function returns an optional value for the type of a value. For example, a dictionary with a value type of string, the function returns a value of type string?. If the value of the key is present before the update, the function return value is the value before the key is updated, and if it does not exist, the function return value is nil:
- If Let OldValue = Airports.updatevalue ("Dublin International", Forkey: "DUB") {
- println ("The old value for DUB is \ (oldValue).")
- }
- Output "The old value for DUB is Dublin.
You can also use the following banner to take a value from a dictionary to a specific key. Because it is possible to use a key that does not exist with a corresponding value, the dictionary's subscript method returns an optional value for that dictionary value type. If there is a value for the key in the dictionary, the following banner returns the value, and if it does not exist, the following banner returns nil:
- If let Airportname = airports["DUB"] {
- println ("The name of the airport is \ (airportname).")
- } else {
- println ("That airport was not in the airports dictionary.")
- }
- Output "The name of the airport is Dublin International."
You can also delete a key value pair by assigning the value of a key to nil by using the following banner method:
- airports["APL"] = "Apple International"
- "Apple International" is not an APL airport, so to remove it airports["APL" = Nil
- The APL key value pair has been removed from the dictionary
You can also use the Removevalueforkey function to remove a key-value pair from a dictionary. If the key value pair exists, the function returns the value that was deleted and returns nil if it does not exist:
- If Let Removedvalue = Airports.removevalueforkey ("DUB") {
- println ("The removed airport ' s name is \ (removedvalue).")
- } else {
- println ("The Airports Dictionary does not contain a value for DUB.")
- }
- Output "The removed airport ' s name is Dublin International."
Iterative access to dictionaries
You can iterate through the for-in loop to access key-value pairs for the entire dictionary. It will return a (key, value) tuple for each element in the dictionary, and you can convert the members in the tuple to variables or constants to use:
- For (Airportcode, Airportname) in airports {
- println ("\ (Airportcode): \ (airportname)")
- }
- Tyo:tokyo//Lhr:london Heathrow
For more information on the for-in cycle, see for Loops.
You can get a collection that iterates through the keys property of the dictionary and the Values property:
- For Airportcode in Airports.keys {
- println ("Airport code: \ (Airportcode)")
- }
- Airport Code:tyo
- Airport CODE:LHR
- For Airportname in Airports.values {
- println ("Airport name: \ (airportname)")
- }
- Airport Name:tokyo
- Airport Name:london Heathrow
If you need to put all the keys or all the values of the dictionary into an array object, you can use the Keys property of the dictionary or the Values property directly:
- Let Airportcodes = Array (Airports.keys)
- Airportcodes for ["Tyo", "LHR"]
- Let Airportnames = Array (airports.values)
- Airportnames for ["Tokyo", "London Heathrow"]
Note: The dictionary type of Swift is not an ordered set, and the order of keys, values, and key-value pairs of the iterated access dictionary is not specified.
Generate an empty dictionary
Like arrays, you can use the initialization syntax to create a specific type of empty dictionary:
- var namesofintegers = Dictionary<int, string> ()
- Namesofintegers is an empty dictionary of type Dictionary<int, string>
This example creates an empty dictionary that stores numeric names, the type of the key is int, and the value is of type string.
If the type information is already provided in the context, you can use the empty dictionary literal [:] To create an empty dictionary:
- NAMESOFINTEGERS[16] = "Sixteen"
- Namesofintegers now contains 1 key-value pairs
- Namesofintegers = [:]
- Namesofintegers again becomes an empty dictionary of type int,string
Note: In fact, Swift's array and dictionary types are implemented through a generic collection. For more information about generic types and collections, see Generics.
The variability of the collection
Both arrays and dictionaries store multiple values in a single collection. If you create an array or dictionary and assign it as a variable, the collection is mutable, which means that after the collection is created, you can change the size of the collection by adding or removing elements. Conversely, if you specify an array or dictionary as a constant, then the array or dictionary is immutable and its capacity size cannot be changed.
For a dictionary, immutable also means that you cannot change the value of a key in the dictionary. An immutable dictionary once the value is set, the contents of it can no longer be changed.
However, the immutability of the array is slightly different from the dictionary. Although you can't do anything that might change the size of the array, you can set a new value for an index in the array. This allows Swift's array to perform optimally in the case of fixed size.
The variable behavior of the Swift array type also affects how the array object is copied and modified, and details can be found in the copy and copy behavior of the collection type.
Note: It is a good idea to define a collection as immutable in any place where you do not need to change the size of the collection. Doing so allows Swift's compiler to optimize the performance of the collection.
Swift Basics-Swift collection types (arrays and dictionaries)