Swift Chapter 3 2018-12-19T13:05:35+00:00

SWIFT CHAPTER 3

TOPICS : (Strings, Characters, Unicode, Accessing and Modifying a String,Substrings, Comparing Strings, Arrays, Set, Dictionaries)

Strings and Characters

A string is a series of characters, such as “hello, world” or “albatross”. Swift strings are represented by the String type. The contents of a String can be accessed in various ways, including as a collection of Character values.

Swift’s String and Character types provide a fast, Unicode-compliant way to work with text in your code. The syntax for string creation and manipulation is lightweight and readable, with a string literal syntax that is similar to C. String concatenation is as simple as combining two strings with the + operator, and string mutability is managed by choosing between a constant or a variable, just like any other value in Swift. You can also use strings to insert constants, variables, literals, and expressions into longer strings, in a process known as string interpolation. This makes it easy to create custom string values for display, storage, and printing.

Despite this simplicity of syntax, Swift’s String type is a fast, modern string implementation. Every string is composed of encoding-independent Unicode characters, and provides support for accessing those characters in various Unicode representations.

Swift’s String type is bridged with Foundation’s NSString class. Foundation also extends String to expose methods defined by NSString. This means, if you import Foundation, you can access those NSString methods on String without casting.

String Literals

You can include predefined String values within your code as string literals. A string literal is a sequence of characters surrounded by double quotation marks ().Use a string literal as an initial value for a constant or variable:

let someString = “Some string literal value”

Multiline String Literals

If you need a string that spans several lines, use a multiline string literal—a sequence of characters surrounded by three double quotation marks:

let quotation = “””

The White Rabbit put on his spectacles. 

“Begin at the beginning,” the King said gravely, “and go on

till you come to the end; then stop.”

“””

A multiline string literal includes all of the lines between its opening and closing quotation marks. The string begins on the first line after the opening quotation marks (“””) and ends on the line before the closing quotation marks, which means that neither of the strings below start or end with a line break:

let singleLineString = “These are the same.”

let multilineString = “””

These are the same.

“””

When your source code includes a line break inside of a multiline string literal, that line break also appears in the string’s value. If you want to use line breaks to make your source code easier to read, but you don’t want the line breaks to be part of the string’s value, write a backslash (\) at the end of those lines:

let softWrappedQuotation = “””

The White Rabbit put on his spectacles.  “Where shall I begin, \

please your Majesty?” he asked.

“Begin at the beginning,” the King said gravely, “and go on \

till you come to the end; then stop.”

“””

To make a multiline string literal that begins or ends with a line feed, write a blank line as the first or last line. For example:

let lineBreaks = “””

This string starts with a line break.

It also ends with a line break.

“””

A multiline string can be indented to match the surrounding code. The whitespace before the closing quotation marks (“””) tells Swift what whitespace to ignore before all of the other lines. However, if you write whitespace at the beginning of a line in addition to what’s before the closing quotation marks, that whitespace is included.

Special Characters in String Literals

String literals can include the following special characters:

The escaped special characters \0 (null character), \\ (backslash), \t (horizontal tab), \n (line feed), \r (carriage return), \” (double quotation mark) and \’ (single quotation mark)

An arbitrary Unicode scalar, written as \u{n}, where n is a 1–8 digit hexadecimal number with a value equal to a valid Unicode code point.The code below shows four examples of these special characters. The wiseWords constant contains two escaped double quotation marks. The dollarSign, blackHeart, and sparklingHeart constants demonstrate the Unicode scalar format:

let wiseWords = “\”Imagination is more important than knowledge\” – Einstein”

// “Imagination is more important than knowledge” – Einstein

let dollarSign = “\u{24}”        // $,  Unicode scalar U+0024

let blackHeart = “\u{2665}”      // ♥,  Unicode scalar U+2665

let sparklingHeart = “\u{1F496}” // 💖, Unicode scalar U+1F496

Because multiline string literals use three double quotation marks instead of just one, you can include a double quotation mark () inside of a multiline string literal without escaping it. To include the text “”” in a multiline string, escape at least one of the quotation marks. For example:

let threeDoubleQuotationMarks = “””

Escaping the first quotation mark \”””

Escaping all three quotation marks \”\”\”

“””

Initializing an Empty String

To create an empty String value as the starting point for building a longer string, either assign an empty string literal to a variable, or initialize a new String instance with initializer syntax:

var emptyString = “”               // empty string literal

var anotherEmptyString = String()  // initializer syntax

// these two strings are both empty, and are equivalent to each other

Find out whether a String value is empty by checking its Boolean isEmpty property:

if emptyString.isEmpty {

    print(“Nothing to see here”)

}

// Prints “Nothing to see here”

String Mutability

You indicate whether a particular String can be modified (or mutated) by assigning it to a variable (in which case it can be modified), or to a constant (in which case it can’t be modified):

var variableString = “Horse”

variableString += ” and carriage”

// variableString is now “Horse and carriage”

let constantString = “Highlander”

constantString += ” and another Highlander”

// this reports a compile-time error – a constant string cannot be modified

Strings Are Value Types

Swift’s String type is a value type. If you create a new String value, that String value is copied when it’s passed to a function or method, or when it’s assigned to a constant or variable. In each case, a new copy of the existing String value is created, and the new copy is passed or assigned, not the original version. Swift’s copy-by-default String behavior ensures that when a function or method passes you a String value, it’s clear that you own that exact String value, regardless of where it came from. You can be confident that the string you are passed won’t be modified unless you modify it yourself.

Working with Characters

You can access the individual Character values for a String by iterating over the string with a forin loop:

for character in “Dog!🐶” {

    print(character)

}

// D

// o

// g

// !

// 🐶

Alternatively, you can create a stand-alone Character constant or variable from a single-character string literal by providing a Character type annotation:

let exclamationMark:  = “!”

String values can be constructed by passing an array of Character values as an argument to its initializer:

let catCharacters: [] = [“C”, “a”, “t”, “!”, 🐱]

Concatenating Strings and Characters

String values can be added together (or concatenated) with the addition operator (+) to create a new String value:

let string1 = “hello”

let string2 = ” there”

var welcome = string1 + string2

// welcome now equals “hello there”

You can also append a String value to an existing String variable with the addition assignment operator (+=):

var instruction = “look over”

instruction += string2

// instruction now equals “look over there”

You can append a Character value to a String variable with the String type’s append() method. You can’t append a String or Character to an existing Character variable, because a Character value must contain a single character only.

let exclamationMark:  = “!”

welcome.append(exclamationMark)

// welcome now equals “hello there!”

String Interpolation

String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions by including their values inside a string literal. You can use string interpolation in both single-line and multiline string literals. Each item that you insert into the string literal is wrapped in a pair of parentheses, prefixed by a backslash (\):

let multiplier = 3

let message = \(multiplier) times 2.5 is \(Double(multiplier) * 2.5)

// message is “3 times 2.5 is 7.5”

In the example above, the value of multiplier is inserted into a string literal as \(multiplier). This placeholder is replaced with the actual value of multiplier when the string interpolation is evaluated to create an actual string.The value of multiplier is also part of a larger expression later in the string. This expression calculates the value of Double(multiplier) * 2.5 and inserts the result (7.5) into the string. In this case, the expression is written as \(Double(multiplier) * 2.5) when it’s included inside the string literal.The expressions you write inside parentheses within an interpolated string can’t contain an unescaped backslash (\), a carriage return, or a line feed. However, they can contain other string literals.

Unicode

Unicode is an international standard for encoding, representing, and processing text in different writing systems. It enables you to represent almost any character from any language in a standardized form, and to read and write those characters to and from an external source such as a text file or web page. Swift’s String and Character types are fully Unicode-compliant, as described in this section.

Unicode Scalars

Behind the scenes, Swift’s native String type is built from Unicode scalar values. A Unicode scalar is a unique 21-bit number for a character or modifier, such as U+0061 for LATIN SMALL LETTER A (“a”), or U+1F425 for FRONT-FACING BABY CHICK (🐥).Note that not all 21-bit Unicode scalars are assigned to a character—some scalars are reserved for future assignment. Scalars that have been assigned to a character typically also have a name, such as LATIN SMALL LETTER A and FRONT-FACING BABY CHICK in the example.

 

Extended Grapheme Clusters

Every instance of Swift’s Character type represents a single extended grapheme cluster. An extended grapheme cluster is a sequence of one or more Unicode scalars that (when combined) produce a single human-readable character.

Here’s an example. The letter é can be represented as the single Unicode scalar é (LATIN SMALL LETTER E WITH ACUTE, or U+00E9). However, the same letter can also be represented as a pair of scalars—a standard letter e (LATIN SMALL LETTER E, or U+0065), followed by the COMBINING ACUTE ACCENT scalar (U+0301). The COMBINING ACUTE ACCENT scalar is graphically applied to the scalar that precedes it, turning an e into an é when it’s rendered by a Unicode-aware text-rendering system.In both cases, the letter é is represented as a single Swift Character value that represents an extended grapheme cluster. In the first case, the cluster contains a single scalar; in the second case, it’s a cluster of two scalars:

let eAcute:  = “\u{E9}”                         // é

let combinedEAcute:  = “\u{65}\u{301}”          // e followed by ́

// eAcute is é, combinedEAcute is é

Extended grapheme clusters are a flexible way to represent many complex script characters as a single Character value. For example, Hangul syllables from the Korean alphabet can be represented as either a precomposed or decomposed sequence. Both of these representations qualify as a single Character value in Swift:

let precomposed:  = “\u{D55C}”                  //

let decomposed:  = “\u{1112}\u{1161}\u{11AB}”   // , ,

// precomposed is , decomposed is

Extended grapheme clusters enable scalars for enclosing marks (such as COMBINING ENCLOSING CIRCLE, or U+20DD) to enclose other Unicode scalars as part of a single Character value:

let enclosedEAcute:  = “\u{E9}\u{20DD}”

// enclosedEAcute is é

Unicode scalars for regional indicator symbols can be combined in pairs to make a single Character value, such as this combination of REGIONAL INDICATOR SYMBOL LETTER U (U+1F1FA) and REGIONAL INDICATOR SYMBOL LETTER S (U+1F1F8):

let regionalIndicatorForUS:  = “\u{1F1FA}\u{1F1F8}”

// regionalIndicatorForUS is 🇺🇸

Counting Characters

To retrieve a count of the Character values in a string, use the count property of the string:

let unusualMenagerie = “Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪

print(“unusualMenagerie has \(unusualMenagerie.count) characters”)

// Prints “unusualMenagerie has 40 characters”

Note that Swift’s use of extended grapheme clusters for Character values means that string concatenation and modification may not always affect a string’s character count.For example, if you initialize a new string with the four-character word cafe, and then append a COMBINING ACUTE ACCENT (U+0301) to the end of the string, the resulting string will still have a character count of 4, with a fourth character of é, not e:

var word = “cafe”

print(“the number of characters in \(word) is \(word.count))

// Prints “the number of characters in cafe is 4”

word += “\u{301}”    // COMBINING ACUTE ACCENT, U+0301

print(“the number of characters in \(word) is \(word.count)”)

// Prints “the number of characters in café is 4”

Extended grapheme clusters can be composed of multiple Unicode scalars. This means that different characters—and different representations of the same character—can require different amounts of memory to store. Because of this, characters in Swift don’t each take up the same amount of memory within a string’s representation. As a result, the number of characters in a string can’t be calculated without iterating through the string to determine its extended grapheme cluster boundaries. If you are working with particularly long string values, be aware that the count property must iterate over the Unicode scalars in the entire string in order to determine the characters for that string. The count of the characters returned by the count property isn’t always the same as the length property of an NSString that contains the same characters. The length of an NSString is based on the number of 16-bit code units within the string’s UTF-16 representation and not the number of Unicode extended grapheme clusters within the string.

Accessing and Modifying a String

You access and modify a string through its methods and properties, or by using subscript syntax.

String Indices

Each String value has an associated index type, String.Index, which corresponds to the position of each Character in the string.

As mentioned above, different characters can require different amounts of memory to store, so in order to determine which Character is at a particular position, you must iterate over each Unicode scalar from the start or end of that String. For this reason, Swift strings can’t be indexed by integer values.Use the startIndex property to access the position of the first Character of a String. The endIndex property is the position after the last character in a String. As a result, the endIndex property isn’t a valid argument to a string’s subscript. If a String is empty, startIndex and endIndex are equal.You access the indices before and after a given index using the index(before:) and index(after:) methods of String. To access an index farther away from the given index, you can use the index(_:offsetBy:) method instead of calling one of these methods multiple times.You can use subscript syntax to access the Character at a particular String index.

let greeting = “Guten Tag!”

greeting[greeting.startIndex]

// G

greeting[greeting.index(before: greeting.endIndex)]

// !

greeting[greeting.index(after: greeting.startIndex)]

// u

let index = greeting.index(greeting.startIndex, offsetBy: 7)

greeting[index]

// a

Attempting to access an index outside of a string’s range or a Character at an index outside of a string’s range will trigger a runtime error.

greeting[greeting.endIndex] // Error

greeting.index(after: greeting.endIndex) // Error

Use the indices property to access all of the indices of individual characters in a string.

for index in greeting.indices {

    print(\(greeting[index]), terminator: “”)

}

// Prints “G u t e n   T a g ! “

You can use the startIndex and endIndex properties and the index(before:), index(after:), and index(_:offsetBy:) methods on any type that conforms to the Collection protocol. This includes String, as shown here, as well as collection types such as Array, Dictionary, and Set.

Inserting and Removing

To insert a single character into a string at a specified index, use the insert(_:at:) method, and to insert the contents of another string at a specified index, use the insert(contentsOf:at:) method.

var welcome = “hello”

welcome.insert(“!”, at: welcome.endIndex)

// welcome now equals “hello!”

welcome.insert(contentsOf: ” there”, at: welcome.index(before: welcome.endIndex))

// welcome now equals “hello there!”

To remove a single character from a string at a specified index, use the remove(at:) method, and to remove a substring at a specified range, use the removeSubrange(_:) method:

welcome.remove(at: welcome.index(before: welcome.endIndex))

// welcome now equals “hello there”

let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex

welcome.removeSubrange(range)

// welcome now equals “hello”

You can use the insert(_:at:), insert(contentsOf:at:), remove(at:), and removeSubrange(_:) methods on any type that conforms to the RangeReplaceableCollection protocol. This includes String, as shown here, as well as collection types such as Array, Dictionary, and Set.

Substrings

When you get a substring from a string—for example, using a subscript or a method like prefix(_:)—the result is an instance of , not another string. Substrings in Swift have most of the same methods as strings, which means you can work with substrings the same way you work with strings. However, unlike strings, you use substrings for only a short amount of time while performing actions on a string. When you’re ready to store the result for a longer time, you convert the substring to an instance of String. For example:

let greeting = “Hello, world!”

let index = greeting.index(of: “,”) ?? greeting.endIndex

let beginning = greeting[..<index]

// beginning is “Hello”

// Convert the result to a String for long-term storage.

let newString = String(beginning)

Like strings, each substring has a region of memory where the characters that make up the substring are stored. The difference between strings and substrings is that, as a performance optimization, a substring can reuse part of the memory that’s used to store the original string, or part of the memory that’s used to store another substring. (Strings have a similar optimization, but if two strings share memory, they are equal.) This performance optimization means you don’t have to pay the performance cost of copying memory until you modify either the string or substring. As mentioned above, substrings aren’t suitable for long-term storage—because they reuse the storage of the original string, the entire original string must be kept in memory as long as any of its substrings are being used.

In the example above, greeting is a string, which means it has a region of memory where the characters that make up the string are stored. Because beginning is a substring of greeting, it reuses the memory that greeting uses. In contrast, newString is a string—when it’s created from the substring, it has its own storage. The figure below shows these relationships:

   

Both String and Substring conform to the  protocol, which means it’s often convenient for string-manipulation functions to accept a StringProtocol value. You can call such functions with either a String or Substring value.

Comparing Strings

Swift provides three ways to compare textual values: string and character equality, prefix equality, and suffix equality.

String and Character Equality

String and character equality is checked with the “equal to” operator (==) and the “not equal to” operator (!=),

let quotation = “We’re a lot alike, you and I.”

let sameQuotation = “We’re a lot alike, you and I.”

if quotation == sameQuotation {

    print(“These two strings are considered equal”)

}

// Prints “These two strings are considered equal”

Two String values (or two Character values) are considered equal if their extended grapheme clusters are canonically equivalent. Extended grapheme clusters are canonically equivalent if they have the same linguistic meaning and appearance, even if they’re composed from different Unicode scalars behind the scenes.For example, LATIN SMALL LETTER E WITH ACUTE (U+00E9) is canonically equivalent to LATIN SMALL LETTER E (U+0065) followed by COMBINING ACUTE ACCENT (U+0301). Both of these extended grapheme clusters are valid ways to represent the character é, and so they’re considered to be canonically equivalent:

// “Voulez-vous un café?” using LATIN SMALL LETTER E WITH ACUTE

let eAcuteQuestion = “Voulez-vous un caf\u{E9}?”

// “Voulez-vous un café?” using LATIN SMALL LETTER E and COMBINING ACUTE ACCENT

let combinedEAcuteQuestion = “Voulez-vous un caf\u{65}\u{301}?”

if eAcuteQuestion == combinedEAcuteQuestion {

    print(“These two strings are considered equal”)

}

// Prints “These two strings are considered equal”

Conversely, LATIN CAPITAL LETTER A (U+0041, or “A”), as used in English, is not equivalent to CYRILLIC CAPITAL LETTER A (U+0410, or “А”), as used in Russian. The characters are visually similar, but don’t have the same linguistic meaning:

let latinCapitalLetterA:  = “\u{41}”

let cyrillicCapitalLetterA:  = “\u{0410}”

if latinCapitalLetterA != cyrillicCapitalLetterA {

    print(“These two characters are not equivalent.”)

}

// Prints “These two characters are not equivalent.”

String and character comparisons in Swift are not locale-sensitive.

Prefix and Suffix Equality

To check whether a string has a particular string prefix or suffix, call the string’s hasPrefix(_:) and hasSuffix(_:) methods, both of which take a single argument of type String and return a Boolean value.The examples below consider an array of strings representing the scene locations from the first two acts of Shakespeare’s Romeo and Juliet:

let romeoAndJuliet = [

    “Act 1 Scene 1: Verona, A public place”,

    “Act 1 Scene 2: Capulet’s mansion”,

    “Act 2 Scene 1: Outside Capulet’s mansion”,

    “Act 2 Scene 2: Capulet’s orchard”,

]

You can use the hasPrefix(_:) method with the romeoAndJuliet array to count the number of scenes in Act 1 of the play:

var act1SceneCount = 0

for scene in romeoAndJuliet {

    if scene.hasPrefix(“Act 1 “) {

        act1SceneCount += 1

    }

}

print(“There are \(act1SceneCount) scenes in Act 1″)

// Prints “There are 2 scenes in Act 1”

Similarly, use the hasSuffix(_:) method to count the number of scenes that take place in or around Capulet’s mansion

var mansionCount = 0

for scene in romeoAndJuliet {

    if scene.hasSuffix(“Capulet’s mansion”) {

        mansionCount += 1

    }

print(\(mansionCount) mansion scenes;”)

// Prints “2 mansion scenes”

The hasPrefix(_:) and hasSuffix(_:) methods perform a character-by-character canonical equivalence comparison between the extended grapheme clusters in each string.

Unicode Representations of Strings

When a Unicode string is written to a text file or some other storage, the Unicode scalars in that string are encoded in one of several Unicode-defined encoding forms. Each form encodes the string in small chunks known as code units. These include the UTF-8 encoding form (which encodes a string as 8-bit code units), the UTF-16 encoding form (which encodes a string as 16-bit code units), and the UTF-32 encoding form (which encodes a string as 32-bit code units).

Swift provides several different ways to access Unicode representations of strings. You can iterate over the string with a forin statement, to access its individual Character values as Unicode extended grapheme clusters. This process is described in Working with Characters.

Alternatively, access a String value in one of three other Unicode-compliant representations:

A collection of UTF-8 code units (accessed with the string’s utf8 property)

A collection of UTF-16 code units (accessed with the string’s utf16 property)

A collection of 21-bit Unicode scalar values, equivalent to the string’s UTF-32 encoding form (accessed with the string’s unicodeScalars property)

Each example below shows a different representation of the following string, which is made up of the characters D, o, g, (DOUBLE EXCLAMATION MARK, or Unicode scalar U+203C), and the 🐶 character (DOG FACE, or Unicode scalar U+1F436):

let dogString = “Dog‼🐶

 

Collection Types

Swift provides three primary collection types, known as arrays, sets, and dictionaries, for storing collections of values. Arrays are ordered collections of values. Sets are unordered collections of unique values. Dictionaries are unordered collections of key-value associations.Arrays, sets, and dictionaries in Swift are always clear about the types of values and keys that they can store. This means that you cannot insert a value of the wrong type into a collection by mistake. It also means you can be confident about the type of values you will retrieve from a collection.Swift’s array, set, and dictionary types are implemented as generic collections. 

Mutability of Collections

If you create an array, a set, or a dictionary, and assign it to a variable, the collection that is created will be mutable. This means that you can change (or mutate) the collection after it’s created by adding, removing, or changing items in the collection. If you assign an array, a set, or a dictionary to a constant, that collection is immutable, and its size and contents cannot be changed.It is good practice to create immutable collections in all cases where the collection does not need to change. Doing so makes it easier for you to reason about your code and enables the Swift compiler to optimize the performance of the collections you create. 

Arrays

An array stores values of the same type in an ordered list. The same value can appear in an array multiple times at different positions.Swift’s Array type is bridged to Foundation’s NSArray class.

Array Type Shorthand Syntax

The type of a Swift array is written in full as Array, where Element is the type of values the array is allowed to store. You can also write the type of an array in shorthand form as [Element]. Although the two forms are functionally identical, the shorthand form is preferred and is used throughout this guide when referring to the type of an array.

Creating an Empty Array

You can create an empty array of a certain type using initializer syntax:

var someInts = [Int]()

print(“someInts is of type [Int] with \(someInts.count) items.”)

// Prints “someInts is of type [Int] with 0 items.”

Note that the type of the someInts variable is inferred to be [Int] from the type of the initializer.

Alternatively, if the context already provides type information, such as a function argument or an already typed variable or constant, you can create an empty array with an empty array literal, which is written as [] (an empty pair of square brackets):

someInts.append(3)

// someInts now contains 1 value of type Int

someInts = []

// someInts is now an empty array, but is still of type [Int]

Creating an Array with a Default Value

Swift’s Array type also provides an initializer for creating an array of a certain size with all of its values set to the same default value. You pass this initializer a default value of the appropriate type (called repeating): and the number of times that value is repeated in the new array (called count):

var threeDoubles = Array(repeating: 0.0, count: 3)

// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]

Creating an Array by Adding Two Arrays Together

You can create a new array by adding together two existing arrays with compatible types with the addition operator (+). The new array’s type is inferred from the type of the two arrays you add together:

var anotherThreeDoubles = Array(repeating: 2.5, count: 3)

// anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]

var sixDoubles = threeDoubles + anotherThreeDoubles

// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]

Creating an Array with an Array Literal

You can also initialize an array with an array literal, which is a shorthand way to write one or more values as an array collection. An array literal is written as a list of values, separated by commas, surrounded by a pair of square brackets:

[value 1, value 2, value 3]

The example below creates an array called shoppingList to store String values:

var shoppingList: [] = [“Eggs”, “Milk”]

// shoppingList has been initialized with two initial items

The shoppingList variable is declared as “an array of string values”, written as [String]. Because this particular array has specified a value type of String, it is allowed to store String values only.The shoppingList array is declared as a variable (with the var introducer) and not a constant (with the let introducer) because more items are added to the shopping list.

In this case, the array literal contains two String values and nothing else. This matches the type of the shoppingList variable’s declaration (an array that can only contain String values), and so the assignment of the array literal is permitted as a way to initialize shoppingList with two initial items.Thanks to Swift’s type inference, you don’t have to write the type of the array if you’re initializing it with an array literal containing values of the same type. The initialization of shoppingList could have been written in a shorter form instead:

var shoppingList = [“Eggs”, “Milk”]

Because all values in the array literal are of the same type, Swift can infer that [String] is the correct type to use for the shoppingList variable.

Accessing and Modifying an Array

You access and modify an array through its methods and properties, or by using subscript syntax.To find out the number of items in an array, check its read-only count property:

print(“The shopping list contains \(shoppingList.count) items.”)

// Prints “The shopping list contains 2 items.”

Use the Boolean isEmpty property as a shortcut for checking whether the count property is equal to 0:

if shoppingList.isEmpty {

    print(“The shopping list is empty.”)

} else {

    print(“The shopping list is not empty.”)

}

// Prints “The shopping list is not empty.”

You can add a new item to the end of an array by calling the array’s append(_:) method:

shoppingList.append(“Flour”)

// shoppingList now contains 3 items, and someone is making pancakes

Alternatively, append an array of one or more compatible items with the addition assignment operator (+=):

shoppingList += [“Baking Powder”]

// shoppingList now contains 4 items

shoppingList += [“Chocolate Spread”, “Cheese”, “Butter”]

// shoppingList now contains 7 items

Retrieve a value from the array by using subscript syntax, passing the index of the value you want to retrieve within square brackets immediately after the name of the array:

var firstItem = shoppingList[0]      // firstItem is equal to “Eggs”

The first item in the array has an index of 0, not 1. Arrays in Swift are always zero-indexed. You can use subscript syntax to change an existing value at a given index:

shoppingList[0] = “Six eggs”

// the first item in the list is now equal to “Six eggs” rather than “Eggs”

When you use subscript syntax, the index you specify needs to be valid. For example, writing shoppingList[shoppingList.count] = “Salt” to try to append an item to the end of the array results in a runtime error.You can also use subscript syntax to change a range of values at once, even if the replacement set of values has a different length than the range you are replacing. The following example replaces “Chocolate Spread”, “Cheese”, and “Butter” with “Bananas” and “Apples”:

shoppingList[4…6] = [“Bananas”, “Apples”]

// shoppingList now contains 6 items

To insert an item into the array at a specified index, call the array’s insert(_:at:) method:

shoppingList.insert(“Maple Syrup”, at: 0)

// shoppingList now contains 7 items

// “Maple Syrup” is now the first item in the list

This call to the insert(_:at:) method inserts a new item with a value of “Maple Syrup” at the very beginning of the shopping list, indicated by an index of 0.Similarly, you remove an item from the array with the remove(at:) method. This method removes the item at the specified index and returns the removed item (although you can ignore the returned value if you do not need it):

let mapleSyrup = shoppingList.remove(at: 0)

// the item that was at index 0 has just been removed

// shoppingList now contains 6 items, and no Maple Syrup

// the mapleSyrup constant is now equal to the removed “Maple Syrup” string

If you try to access or modify a value for an index that is outside of an array’s existing bounds, you will trigger a runtime error. You can check that an index is valid before using it by comparing it to the array’s count property. The largest valid index in an array is count – 1 because arrays are indexed from zero—however, when count is 0 (meaning the array is empty), there are no valid indexes.

Any gaps in an array are closed when an item is removed, and so the value at index 0 is once again equal to “Six eggs”:

firstItem = shoppingList[0]

// firstItem is now equal to “Six eggs”

If you want to remove the final item from an array, use the removeLast() method rather than the remove(at:) method to avoid the need to query the array’s count property. Like the remove(at:) method, removeLast() returns the removed item:

let apples = shoppingList.removeLast()

// the last item in the array has just been removed

Iterating Over an Array

You can iterate over the entire set of values in an array with the forin loop:

for item in shoppingList {

    print(item)

}

// Six eggs

// Milk

// Flour

// Baking Powder

// Bananas

If you need the integer index of each item as well as its value, use the enumerated() method to iterate over the array instead. For each item in the array, the enumerated() method returns a tuple composed of an integer and the item. The integers start at zero and count up by one for each item; if you enumerate over a whole array, these integers match the items’ indices. You can decompose the tuple into temporary constants or variables as part of the iteration:

for (index, value) in shoppingList.enumerated() {

    print(“Item \(index + 1): \(value))

}

// Item 1: Six eggs

// Item 2: Milk

// Item 3: Flour

// Item 4: Baking Powder

// Item 5: Bananas

Sets

A set stores distinct values of the same type in a collection with no defined ordering. You can use a set instead of an array when the order of items is not important, or when you need to ensure that an item only appears once.Swift’s Set type is bridged to Foundation’s NSSet class.

Hash Values for Set Types

A type must be hashable in order to be stored in a set—that is, the type must provide a way to compute a hash value for itself. A hash value is an Int value that is the same for all objects that compare equally, such that if a == b, it follows that a.hashValue == b.hashValue.

All of Swift’s basic types (such as String, Int, Double, and Bool) are hashable by default, and can be used as set value types or dictionary key types. Enumeration case values without associated values are also hashable by default.

You can use your own custom types as set value types or dictionary key types by making them conform to the Hashable protocol from Swift’s standard library. Types that conform to the Hashable protocol must provide a gettable Int property called hashValue. The value returned by a type’s hashValue property is not required to be the same across different executions of the same program, or in different programs. Because the Hashable protocol conforms to Equatable, conforming types must also provide an implementation of the equals operator (==). The Equatable protocol requires any conforming implementation of == to be an equivalence relation. That is, an implementation of == must satisfy the following three conditions, for all values a, b, and c:

a == a (Reflexivity)

a == b implies b == a (Symmetry)

a == b && b == c implies a == c (Transitivity)

Set Type Syntax

The type of a Swift set is written as Set, where Element is the type that the set is allowed to store. Unlike arrays, sets do not have an equivalent shorthand form.

 

Creating and Initializing an Empty Set

You can create an empty set of a certain type using initializer syntax:

var letters = Set<>()

print(“letters is of type Set with \(letters.count) items.”)

// Prints “letters is of type Set with 0 items.”

The type of the letters variable is inferred to be Set, from the type of the initializer.

Alternatively, if the context already provides type information, such as a function argument or an already typed variable or constant, you can create an empty set with an empty array literal:

letters.insert(“a”)        // letters now contains 1 value of type Character

letters = []             // letters is now an empty set, but is still of type Set

Creating a Set with an Array Literal

You can also initialize a set with an array literal, as a shorthand way to write one or more values as a set collection.The example below creates a set called favoriteGenres to store String values:

var favoriteGenres: <> = [“Rock”, “Classical”, “Hip hop”]        // favoriteGenres has been initialized with three initial items

The favoriteGenres variable is declared as “a set of String values”, written as Set. Because this particular set has specified a value type of String, it is only allowed to store String values. Here, the favoriteGenres set is initialized with three String values (“Rock”, “Classical”, and “Hip hop”), written within an array literal.The favoriteGenres set is declared as a variable (with the var introducer) and not a constant (with the let introducer) because items are added and removed.A set type cannot be inferred from an array literal alone, so the type Set must be explicitly declared. However, because of Swift’s type inference, you don’t have to write the type of the set if you’re initializing it with an array literal containing values of the same type. The initialization of favoriteGenres could have been written in a shorter form instead:

var favoriteGenres:  = [“Rock”, “Classical”, “Hip hop”]

Because all values in the array literal are of the same type, Swift can infer that Set is the correct type to use for the favoriteGenres variable.

Accessing and Modifying a Set

You access and modify a set through its methods and properties.To find out the number of items in a set, check its read-only count property:

print(“I have \(favoriteGenres.count) favorite music genres.”)

// Prints “I have 3 favorite music genres.”

Use the Boolean isEmpty property as a shortcut for checking whether the count property is equal to 0:

if favoriteGenres.isEmpty {

    print(“As far as music goes, I’m not picky.”)

} else {

    print(“I have particular music preferences.”)

}

// Prints “I have particular music preferences.”

You can add a new item into a set by calling the set’s insert(_:) method:

favoriteGenres.insert(“Jazz”)

// favoriteGenres now contains 4 items

You can remove an item from a set by calling the set’s remove(_:) method, which removes the item if it’s a member of the set, and returns the removed value, or returns nil if the set did not contain it. Alternatively, all items in a set can be removed with its removeAll() method.

if let removedGenre = favoriteGenres.remove(“Rock”) {

    print(\(removedGenre)? I’m over it.”)

} else {

    print(“I never much cared for that.”)

}         // Prints “Rock? I’m over it.”

To check whether a set contains a particular item, use the contains(_:) method.

if favoriteGenres.contains(“Funk”) {

    print(“I get up on the good foot.”)

} else {

    print(“It’s too funky in here.”)

}       // Prints “It’s too funky in here.”

Iterating Over a Set

You can iterate over the values in a set with a forin loop.

for genre in favoriteGenres {

    print(\(genre))

}

// Jazz

// Hip hop

// Classical

Swift’s Set type does not have a defined ordering. To iterate over the values of a set in a specific order, use the sorted() method, which returns the set’s elements as an array sorted using the < operator.

for genre in favoriteGenres.sorted() {

    print(\(genre))

}

// Classical

// Hip hop

// Jazz

Performing Set Operations

You can efficiently perform fundamental set operations, such as combining two sets together, determining which values two sets have in common, or determining whether two sets contain all, some, or none of the same values.

Fundamental Set Operations

The illustration below depicts two sets—a and b—with the results of various set operations represented by the shaded regions.

   

Use the intersection(_:) method to create a new set with only the values common to both sets.

Use the symmetricDifference(_:) method to create a new set with values in either set, but not both.

Use the union(_:) method to create a new set with all of the values in both sets.

Use the subtracting(_:) method to create a new set with values not in the specified set.

let oddDigits:  = [1, 3, 5, 7, 9]

let evenDigits:  = [0, 2, 4, 6, 8]

let singleDigitPrimeNumbers:  = [2, 3, 5, 7]

oddDigits.union(evenDigits).sorted()  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

oddDigits.intersection(evenDigits).sorted()  // []

oddDigits.subtracting(singleDigitPrimeNumbers).sorted()  // [1, 9]

oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()  // [1, 2, 9]

Set Membership and Equality

The illustration below depicts three sets—a, b and c—with overlapping regions representing elements shared among sets. Set a is a superset of set b, because a contains all elements in b. Conversely, set b is a subset of set a, because all elements in b are also contained by a. Set b and set c are disjoint with one another, because they share no elements in common.

   

Use the “is equal” operator (==) to determine whether two sets contain all of the same values.

Use the isSubset(of:) method to determine whether all of the values of a set are contained in the specified set.Use the isSuperset(of:) method to determine whether a set contains all of the values in a specified set.Use the isStrictSubset(of:) or isStrictSuperset(of:) methods to determine whether a set is a subset or superset, but not equal to, a specified set.Use the isDisjoint(with:) method to determine whether two sets have no values in common.

let houseAnimals:  = [🐶, 🐱]

let farmAnimals:  = [🐮, 🐔, 🐑, 🐶, 🐱]

let cityAnimals:  = [🐦, 🐭]

houseAnimals.isSubset(of: farmAnimals)  // true

farmAnimals.isSuperset(of: houseAnimals)  // true

farmAnimals.isDisjoint(with: cityAnimals)  // true

Dictionaries

A dictionary stores associations between keys of the same type and values of the same type in a collection with no defined ordering. Each value is associated with a unique key, which acts as an identifier for that value within the dictionary. Unlike items in an array, items in a dictionary do not have a specified order. You use a dictionary when you need to look up values based on their identifier, in much the same way that a real-world dictionary is used to look up the definition for a particular word.Swift’s Dictionary type is bridged to Foundation’s NSDictionary class.

Dictionary Type Shorthand Syntax

The type of a Swift dictionary is written in full as Dictionary<Key, Value>, where Key is the type of value that can be used as a dictionary key, and Value is the type of value that the dictionary stores for those keys.A dictionary Key type must conform to the Hashable protocol, like a set’s value type.

You can also write the type of a dictionary in shorthand form as [Key: Value]. Although the two forms are functionally identical, the shorthand form is preferred and is used throughout this guide when referring to the type of a dictionary.

Creating an Empty Dictionary

As with arrays, you can create an empty Dictionary of a certain type by using initializer syntax:

var namesOfIntegers = [Int: String]()

// namesOfIntegers is an empty [Int: String] dictionary

This example creates an empty dictionary of type [Int: String] to store human-readable names of integer values. Its keys are of type Int, and its values are of type String.If the context already provides type information, you can create an empty dictionary with an empty dictionary literal, which is written as [:] (a colon inside a pair of square brackets):

namesOfIntegers[16] = “sixteen”    // namesOfIntegers now contains 1 key-value pair

namesOfIntegers = [:].  // namesOfIntegers is once again an empty dictionary of type [Int: String]

Creating a Dictionary with a Dictionary Literal

You can also initialize a dictionary with a dictionary literal, which has a similar syntax to the array literal seen earlier. A dictionary literal is a shorthand way to write one or more key-value pairs as a Dictionary collection.A key-value pair is a combination of a key and a value. In a dictionary literal, the key and value in each key-value pair are separated by a colon. The key-value pairs are written as a list, separated by commas, surrounded by a pair of square brackets:

[key 1: value 1, key 2: value 2, key 3: value 3]

The example below creates a dictionary to store the names of international airports. In this dictionary, the keys are three-letter International Air Transport Association codes, and the values are airport names:

var airports: [: ] = [“YYZ”: “Toronto Pearson”, “DUB”: “Dublin”]

The airports dictionary is declared as having a type of [String: String], which means “a Dictionary whose keys are of type String, and whose values are also of type String”.

The airports dictionary is initialized with a dictionary literal containing two key-value pairs. The first pair has a key of “YYZ” and a value of “Toronto Pearson”. The second pair has a key of “DUB” and a value of “Dublin”.This dictionary literal contains two String: String pairs. This key-value type matches the type of the airports variable declaration (a dictionary with only String keys, and only String values), and so the assignment of the dictionary literal is permitted as a way to initialize the airports dictionary with two initial items.As with arrays, you don’t have to write the type of the dictionary if you’re initializing it with a dictionary literal whose keys and values have consistent types. The initialization of airports could have been written in a shorter form instead:

var airports = [“YYZ”: “Toronto Pearson”, “DUB”: “Dublin”]

Because all keys in the literal are of the same type as each other, and likewise all values are of the same type as each other, Swift can infer that [String: String] is the correct type to use for the airports dictionary.

Accessing and Modifying a Dictionary

You access and modify a dictionary through its methods and properties, or by using subscript syntax.As with an array, you find out the number of items in a Dictionary by checking its read-only count property:

print(“The airports dictionary contains \(airports.count) items.”)

// Prints “The airports dictionary contains 2 items.”

Use the Boolean isEmpty property as a shortcut for checking whether the count property is equal to 0:

if airports.isEmpty {

    print(“The airports dictionary is empty.”)

} else {

    print(“The airports dictionary is not empty.”)

}

// Prints “The airports dictionary is not empty.”

You can add a new item to a dictionary with subscript syntax. Use a new key of the appropriate type as the subscript index, and assign a new value of the appropriate type:

airports[“LHR”] = “London”      // the airports dictionary now contains 3 items

You can also use subscript syntax to change the value associated with a particular key:

airports[“LHR”] = “London Heathrow”        // the value for “LHR” has been changed to “London Heathrow”

As an alternative to subscripting, use a dictionary’s updateValue(_:forKey:) method to set or update the value for a particular key. Like the subscript examples above, the updateValue(_:forKey:) method sets a value for a key if none exists, or updates the value if that key already exists. Unlike a subscript, however, the updateValue(_:forKey:) method returns the old value after performing an update. This enables you to check whether or not an update took place.

The updateValue(_:forKey:) method returns an optional value of the dictionary’s value type. For a dictionary that stores String values, for example, the method returns a value of type String?, or “optional String”. This optional value contains the old value for that key if one existed before the update, or nil if no value existed:

if let oldValue = airports.updateValue(“Dublin Airport”, forKey: “DUB”) {

    print(“The old value for DUB was \(oldValue).”)

}       // Prints “The old value for DUB was Dublin.”

You can also use subscript syntax to retrieve a value from the dictionary for a particular key. Because it is possible to request a key for which no value exists, a dictionary’s subscript returns an optional value of the dictionary’s value type. If the dictionary contains a value for the requested key, the subscript returns an optional value containing the existing value for that key. Otherwise, the subscript returns nil:

if let airportName = airports[“DUB”] {

    print(“The name of the airport is \(airportName).”)

} else {

    print(“That airport is not in the airports dictionary.”)

}                  // Prints “The name of the airport is Dublin Airport.”

You can use subscript syntax to remove a key-value pair from a dictionary by assigning a value of nil for that key:

airports[“APL”] = “Apple International”

// “Apple International” is not the real airport for APL, so delete it

airports[“APL”] = nil

// APL has now been removed from the dictionary

Alternatively, remove a key-value pair from a dictionary with the removeValue(forKey:) method. This method removes the key-value pair if it exists and returns the removed value, or returns nil if no value existed:

if let removedValue = airports.removeValue(forKey: “DUB”) {

    print(“The removed airport’s name is \(removedValue).”)

} else {

    print(“The airports dictionary does not contain a value for DUB.”)

}

// Prints “The removed airport’s name is Dublin Airport.”

Iterating Over a Dictionary

You can iterate over the key-value pairs in a dictionary with a forin loop. Each item in the dictionary is returned as a (key, value) tuple, and you can decompose the tuple’s members into temporary constants or variables as part of the iteration:

for (airportCode, airportName) in airports {

    print(\(airportCode): \(airportName))

}

// YYZ: Toronto Pearson

// LHR: London Heathrow

You can also retrieve an iterable collection of a dictionary’s keys or values by accessing its keys and values properties:

for airportCode in airports.keys {

    print(“Airport code: \(airportCode))

}

// Airport code: YYZ

// Airport code: LHR

for airportName in airports.values {

    print(“Airport name: \(airportName))

}

// Airport name: Toronto Pearson

// Airport name: London Heathrow

If you need to use a dictionary’s keys or values with an API that takes an Array instance, initialize a new array with the keys or values property:

let airportCodes = [String](airports.keys)        // airportCodes is [“YYZ”, “LHR”]

let airportNames = [String](airports.values)          // airportNames is [“Toronto Pearson”, “London Heathrow”]

Swift’s Dictionary type does not have a defined ordering. To iterate over the keys or values of a dictionary in a specific order, use the sorted() method on its keys or values property.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.