Chapter    10

Tuples, Sets, and Structures

Variables are good for storing individual chunks of data while arrays and dictionaries are good for storing lists of the same data type. For greater flexibility, Swift also offers additional data structures called tuples and sets.

A tuple lets you store related data in one place that may consist of different data types such as a string and an integer, which could represent a person’s name and an employee ID number. A set is similar to an array or a dictionary in letting you store two or more chunks of data that consists of the same data type, such as strings or integers.

To group related data together, Swift also offers structures. With a structure, you can define the data type you want to group together in any combination, such as two strings and a floating-point value. Structures are a way to group different data types together.

Perhaps the biggest advantage of both tuples and structures is when you combine them with other data structures. Instead of creating an array of integers, you could create an array of tuples or an array of structures. This gives you the flexibility to store different data types together and store multiple copies of similar data.

Using Tuples

Suppose you wanted to store somebody’s name and age. You could create two separate variables like this:

var name : String
var age : Int
name = "Janice Parker"
age = 47

Creating two or more separate variables to store related data can be troublesome because there’s no connection between the two variables to show any relationship. To solve this problem, Swift offers a unique data structure called a tuple.

A tuple can store two or more chunks of data in a single variable where the separate chunks of data can even be completely different data types such as a string and an integer. Declaring a tuple is just like declaring a variable. The main difference is that instead of defining a single data type, you can define multiple data types enclosed in parentheses like this:

var tupleName : (DataType1, DataType2)

Just like declaring variables, you have to declare a unique name for your tuple. Then you have to define how many different chunks of data to hold and their data types. Tuples can hold two or more chunks of data, but the more data a tuple holds, the clumsier it can be to understand and retrieve data.

One way to create a tuple is to declare a tuple name and the data types it can hold. The number of data types listed also defines the number of data chunks the tuple can store. So if you wanted to store a string and an integer in a tuple, you could use the following Swift code:

var person : (String, Int)

Then you could store data in that tuple like this:

person = ("Janice Parker", 47)

When assigning data to a tuple, make sure you have both the proper data types and the correct number of data chunks. So the following would fail because the person tuple expects a string first and then an integer, not an integer first and then a string:

person = (47, "Janice Parker") // This would fail

A second way to define a tuple is to simply give it data and let Swift infer the data type such as:

var person = ("Janice Parker", 47)

If you define a tuple by listing its data types, or if you let Swift infer the data types by the type of data you store, it’s not always clear what each chunk of data represents. To make it easier to identify the different chunks of data, Swift also lets you name your data types such as:

var person : (name: String, age: Int)

or if you want Swift to infer the data types by assigning data directly into the tuple:

var person = (name: "Janice Parker", age: 47)

Named tuples help clarify what each data chunk represents. In this case, the string represents a name and the integer represents an age.

Accessing Data in a Tuple

Once you’ve created a tuple and stored data in it, you’ll need to retrieve that data eventually. Since a tuple contains two or more chunks of data, Swift offers three ways to retrieve the data you want.

First, you can create multiple variables to access the tuple data as follows:

var petInfo = ("Rover", 38, true)

var (dog, number, yesValue) = petInfo
print (dog)
print (number)
print (yesValue)

In the first line of code, petInfo is a tuple. that contains three chunks of data: a string (“Rover”), an integer (38), and a Boolean value (true).

The second line of code creates three variables (dog, number, yesValue) and assigns their values to the corresponding data stored in the petInfo tuple. That means dog stores “Rover,” number stores 38, and yesValue stores true. The print commands simply print this data out to verify that it retrieved information from the tuple.

To access data from a tuple, you must know the order that the tuple stores data. So if you wanted to retrieve a string from the petInfo tuple, you’d have to know that the petInfo tuple stores names as its first chunk of data, a number as its second chunk of data, and a Boolean value as its third chunk of data.

If you don’t want to retrieve all the values stored in a tuple, you can just create a variable to store the data you want and use the underscore character (_) as an empty placeholder to represent each additional value in the tuple that you want to ignore.

That means you still need to know the number of data chunks the tuple holds so you can identify the one chunk of data that you want to retrieve. For example, if a tuple contains three items, you can retrieve the first item like this:

var petInfo = ("Rover", 38, true)
var (pet,_,_) = petInfo
print (pet)

This would store “Rover” in the pet variable so the print command would print “Rover.”.

If you just wanted to retrieve the middle value, you could type the following:

var petInfo = ("Rover", 38, true)
var (_,aValue,_) = petInfo
print (aValue)

This would store the number 38 into the aValue variable and then the print command would print 38.

The underscore characters act as placeholders that identify data in a tuple that you want to ignore. If you omit the underscore characters, Swift won’t know which particular data you want out of a tuple. To retrieve data from a tuple, you must know the number and order of the items that the tuple stores.

A second way to retrieve values from a tuple is to use index numbers where the first element is assigned index number 0, the second element is assigned index number 1, and so on. For example, you might store data in a tuple like this:

var petInfo = ("Rover", 38, true)
print (petInfo.0)
print (petInfo.1)
print (petInfo.2)

The first item in the tuple is assigned index number 0 so the combination of the tuple name (such as petInfo) followed by the index number lets you directly retrieve a specific tuple value. So petInfo.0 retrieves “Rover,” petInfo.1 retrieves 38, and petInfo.2 retrieves true.

A third method for accessing data in a tuple involves using names. To uses this method, you must first assign names to each tuple data. For example, the following Swift code defines two names called “name” and “age”:

var tupleName = (name: "Bridget", age: 31)

Now you can access the tuple data by referencing the tuple name followed by the identifying name for each data like this:

print (tupleName.name)  // Prints "Bridget"
print (tupleName.age)   // Prints 31

All three methods give you different ways to access data stored in tuples so just use the method you like best. For clarity, naming the specific elements of a tuple makes your code easier to understand but at the sacrifice of forcing you to name your tuple data. The index number method and the multiple variable method may be simpler, but can be less clear and requires you to know the exact order of the data you want to retrieve.

To see how to work with tuples, create a new playground by following these steps:

  1. Start Xcode.
  2. Choose File image New image Playground. (If you see the Xcode welcome screen, you can also click on Get started with a playground.) Xcode asks for a playground name and platform.
  3. Click in the Name text field and type TuplePlayground.
  4. Click in the Platform pop-up menu and choose OS X. Xcode asks where you want to save your playground file.
  5. Click on a folder where you want to save your playground file and click the Create button. Xcode displays the playground file.
  6. Edit the code as follows:
    import Cocoa

    var tupleName = (greeting: "Happy Birthday", age: 58, happy: true)

    // Method #1
    var (message, howOld, mood) = tupleName
    print (message)
    print (howOld)
    print (mood)

    var (_,stuff,_) = tupleName
    print (stuff)

    // Method #2

    print (tupleName.0)
    print (tupleName.1)
    print (tupleName.2)

    // Method #3

    print (tupleName.greeting)
    print (tupleName.age)
    print (tupleName.happy)

When you try all three methods for accessing values from a tuple, you can see how they all work alike. Tuples make it easy to group related data together in a single variable so you can easily keep related information organized. Then you can choose to retrieve data from a tuple using one of three different methods as shown in Figure 10-1.

9781484212349_Fig10-01.jpg

Figure 10-1. Three different ways to retrieve data from a tuple

Using Sets

Arrays and dictionaries are designed to store lists of the same data types such as a list of strings or a list of integers. The difference between arrays and dictionaries is how you retrieve data. Arrays force you to retrieve data by location using index values. Dictionaries let you retrieve data using a key, but you must define a unique key for each chunk of data you store.

Sets represent another way to store lists of identical data types such as strings or floating-point numbers. One speed advantage of a set is determining if something is stored or not. If you store data in an arrays, you’d have to exhaustively search throughout the entire array to determine if an array stores a particular item. If you store data in a dictionary, you have to know the key stored with that value, or you have to exhaustively search through the dictionary’s list of values.

Sets let you quickly determine the following far faster than arrays or dictionaries:

  • If an item is stored in a set or not
  • If a set contains exactly the same items as another set
  • If a set is a subset of another set (contains the same items as a larger set)
  • If a set is a superset of another set (contains the same items and more than a smaller set)
  • If two sets contain the same items or not

Sets make it easy to compare two different groups of data in ways that arrays and dictionaries can’t do as easily.

Creating a Set

To create a set, you can define the name of the set and the type of data the set can hold like this:

var setName = Set<DataType>()>()

The set name should ideally be descriptive of its contents such as memberSet. The data type can be Int (integer), String (strings), Float or Double (decimal numbers), or even the name of another data structure.

A second way to create a set to define it contents within square brackets and let Swift infer the data type. All data must be of the same data type such as:

var setName = Set ([Data1, Data2, Data2 ... DataN])

Notice that if you omit the “Set” keyword and the enclosing parentheses, you’ll define an array, not a set like this:

var thisIsAnArray = [Data1, Data2, Data2 ... DataN]

Adding and Removing Items from a Set

With a set, you can add new items at any time, just as long as the new item is the same data type as the existing data. To add an item to a set, just specify the set name, the insert command, and the data you want to add inside parentheses like this

setName.insert(data)

You must specify the array name to add data to and put the actual data in parentheses. Make sure the data you add is of the proper data type. So if you want to add data to a set that currently holds only integers, you can only add another integer to that set.

If you try to add data that already exists in the set, nothing will happen. That means if a set contains the number 53, you can’t add another copy of 53 into that set.

To remove data from a set, you just specify the set name, the remove command, and the data you want to remove enclosed in parentheses like this:

setName.remove(data)

If you try to remove data that doesn’t exist in the set, then the remove command returns a nil value. However if the remove command succeeds in removing data from a set, it returns an optional variable. So if you remove data from a set and store it in a variable like this:

var variableName = setName.remove(data)

The value stored in the variable can be accessed by using an exclamation mark like this:

print (variableName!)

If you want to remove all items in a set, specify the set name and the removeAll command like this:

setName.removeAll()

To see how to create a set and add and remove data from it, create a new playground by following these steps:

  1. Start Xcode.
  2. Choose File image New image Playground. (If you see the Xcode welcome screen, you can also click on Get started with a playground.) Xcode asks for a playground name and platform.
  3. Click in the Name text field and type SetPlayground.
  4. Click in the Platform pop-up menu and choose OS X. Xcode asks where you want to save your playground file.
  5. Click on a folder where you want to save your playground file and click the Create button. Xcode displays the playground file.
  6. Edit the code as follows:
    import Cocoa

    var setOne = Set([2, 45, -9, 8, -34])
    var setTwo = Set<Int>()

    setTwo = [34, 90, -83]

    setOne.insert(65)
    setTwo.insert(-381)

    var temp = setOne.remove(45)
    print (temp)
    print (temp!)
    setOne.removeAll()

This Swift code creates a set called setOne by storing data directly and letting Swift infer the data types, which are integers. Then it creates a second set called setTwo, defined as holding only integers (Int).

After creating setTwo, the next line stores three integers in that set. The two insert commands store different integers into both setOne and setTwo. When the code removes the number 45 from setOne, it stores 45 as an optional variable in the temp variable. To access the actual value, you have to unwrap the optional variable using the exclamation mark (!).

Finally, the removeAll command empties setOne so it contains nothing as shown in Figure 10-2.

9781484212349_Fig10-02.jpg

Figure 10-2. Creating sets, inserting data in a set, and removing data from a set

Querying a Set

Once you have a set, you can use the following commands to get information about that set:

  • count – counts the number of items in a set
  • isEmpty – checks if a set is empty (contains 0 items)
  • isSubsetOf – checks if one set is wholly contained within another set
  • isSupersetOf – checks if one set contains all the items of another set
  • isDisjointWith – checks if two sets have no items in common

Whatever the result of these commands, they never affect the data stored in a set.

The count command returns an integer value and just requires the set name and the count command like this:

setName.count

You can also assign this value to a variable such as:

var total = setName.count

The isEmpty command returns a Boolean value of true if a set has zero items in it. Otherwise it returns false. Just specify the set name followed by the isEmpty command like this:

setOne.isEmpty

The isSubsetOf command checks if one set contains items that are also contained in a second set. Only if this second set contains every item from the first set is it considered a subset.

The isSupersetOf command checks if one set is larger and contains all the same items as a smaller set. Only if this first set is larger and has all its items stored in the second set is it considered a superset.

The isDisjointWith command compares two sets. If they have no items in common, then this command returns true. Otherwise it returns false.

To see how to query a set, follow these steps:

  1. Make sure the SetPlayground file is loaded in Xcode.
  2. Edit the code as follows:
    import Cocoa

    var mySet = Set(["Fred", "Cindy", "Jody", "Grant"])
    print (mySet.isEmpty)
    mySet.count
    mySet.removeAll()
    print (mySet.isEmpty)

    var myNewSet = Set(["John", "Oscar"])
    var myOtherSet = Set(["John", "Oscar", "Sally"])
    var myThirdSet = Set(["Rick", "Vinny"])

    myNewSet.isSubsetOf(myOtherSet)
    myOtherSet.isSupersetOf(myNewSet)
    myNewSet.isDisjointWith(myThirdSet)

This code creates a set that holds four strings. It uses the isEmpty command to check if the set is empty (false). Then it counts the set (it has 4 items). Finally, it removes all the items from the set and uses the isEmpty command again to check if the set is empty (true).

The next batch of code creates three different sets called myNewSet, myOtherSet, and myThirdSet, which are filled with different names. Then the isSubsetOf command checks if all the items in myNewSet [“John,” “Oscar”]are also in the myOtherSet [“John,” “Oscar,” “Sally”], which is true.

The isSupersetOf command checks if myOtherSet [“John,” “Oscar,” “Sally”] contains more items and also contains all the items stored in myNewSet [“John,” “Oscar”], which is also true.

Finally, the isDisjointWith command checks if myNewSet [“John,” “Oscar”] has nothing in common with myThirdSet [“Rick,” “Vinny”], which is also true as shown in Figure 10-3.

9781484212349_Fig10-03.jpg

Figure 10-3. Querying a set

Manipulating Sets

When you have two or more sets, you can perform operations on both of sets that creates a third set. Some common set operations include:

  • union – combines all items from two sets into a new set
  • subtract – removes the items of a second set from a first set to form a new set
  • intersect – finds the common items in both sets and stores them in a new set
  • exclusiveOr – finds items contained in one set or another, but not items in both sets

Think of the union command like adding two sets together and the subtract command like subtracting one set from another. The union command specifies two set names like this:

firstSet.union(secondSet)

Think of this as equivalent to firstSet + secondSet where all items from both sets get combined into a third set.

The subtract command specifies two set names, but the order makes a difference such as:

thirdSet.subtract(firstSet)
firstSet.subtract(thirdSet)

These two commands can give different results depending on the contents of each set. Suppose thirdSet contains {1, 2, 3, 4, 5} and firstSet contains [1, 3, 5, 7}. The thirdSet.subtract(firstSet) command works like this:

{1, 2, 3, 4, 5}  thirdSet
[1, 3, 5, 7}     firstSet

Both sets contain 1, 3, and 5 so those numbers get eliminated. Take 1, 3, and 5 out of thirdSet and you’re left with {2, 4}.

The firstSet.subtract(thirdSet) command works like this:

[1, 3, 5, 7}     firstSet
{1, 2, 3, 4, 5}  thirdSet

Both sets contain 1, 3, and 5 so those numbers get eliminated. Take 1, 3, and 5 out of firstSet and you’re left with {7}.

The intersect command finds items in common between two sets. The exclusiveOr command finds items that are not in both sets. Think of the exclusiveOr command as the opposite of the intersect command.

To see how these four different ways to manipulate sets work, follow these steps:

  1. Make sure the SetPlayground file is loaded in Xcode.
  2. Edit the code as follows:
    import Cocoa

    var firstSet = Set([1, 3, 5, 7])
    var secondSet = Set([2, 4, 6, 8])
    var thirdSet = Set ([1, 2, 3, 4, 5])

    firstSet.union(secondSet)
    secondSet.subtract(firstSet)
    firstSet.subtract(secondSet)
    firstSet.subtract(thirdSet)
    thirdSet.subtract(firstSet)

    firstSet.intersect(thirdSet)
    firstSet.exclusiveOr(thirdSet)

Notice how the subtract command works differently depending on the order you list the two sets as shown in Figure 10-4.

9781484212349_Fig10-04.jpg

Figure 10-4. Manipulating sets

Using Structures

Both tuples and sets are built-in features of Swift. Structures are a unique way for you to group different types of data in a single place. With a traditional variable, you can only store one chunk of data at a time. With a structure, you can define two or more chunks of data to store in a single variable. Variables declared inside a structure are called properties.

A structure that stores two chunks of data would look like this:

struct structureName {
    var variableName1 : dataType
    var variableName2 : dataType
}

Remember, the data type of each variable can be simple data types such as Int, String, or Double, or they can be more complicated data types such as arrays, tuples, sets, or dictionaries.

You can define two or more variables inside a structure where each variable can contain different data types such as a string or an integer. No matter how many properties a structure holds, you must initialize the properties before you can store data in them.

Swift provides three ways to initialize properties. First, you can define an initial value for each property like this:

struct structureName {
    var variableName1 : dataType = initialValue
    var variableName2 : dataType = initialValue
}

To simplify the property declaration, a second way is to omit the data type and let Swift infer the data type like this:

struct structureName {
    var variableName1 = initialValue
    var variableName2 = initialValue
}

When you assign an initial value to properties, you can create a variable to represent that structure like this:

var variableName = structureName()

A third way to initialize structure properties is to create an init function. This means you must create a list of property names and their data types. Then assign values to those properties when you create a variable to represent that structure.

For example, suppose you wanted to store information about a person such as his or her name, e-mail address, and phone number. Instead of creating three separate variables, you could create a single structure like this:

struct person {
    var name : String
    var email : String
    var phone : String
}

When you create a variable based on this structure, you need to include initial values such as:

var workers = person(name: "Sue", email: "[email protected]", phone: "555-1234")

Creating a structure involves two parts:

  • Create a structure with two or more variables (properties)
  • Create a variable to represent that structure and assign initial values to those properties

Storing and Retrieving Items from a Structure

A structure lets you define the type of related data to store. Then you need to create a variable name to represent that structure. Finally, to store in a structure, you need to specify the structure name and the variable name separated by a period like this:

structureVariable.variableName = value

To retrieve data from a structure, you can assign a variable to a structure’s variable like this:

var variableName = structureVariable.variableName

To see how to create a structure, initialize its properties, and add and retrieve data, create a new playground by following these steps:

  1. Start Xcode.
  2. Choose File image New image Playground. (If you see the Xcode welcome screen, you can also click on Get started with a playground.) Xcode asks for a playground name and platform.
  3. Click in the Name text field and type StructurePlayground.
  4. Click in the Platform pop-up menu and choose OS X. Xcode asks where you want to save your playground file.
  5. Click on a folder where you want to save your playground file and click the Create button. Xcode displays the playground file.
  6. Edit the code as follows:
    import Cocoa

    struct pet {
        var name : String = ""
        var age : Int = 0
    }

    var dog = pet()
    dog.name = "Fido"
    dog.age = 4

    print (dog.name)
    print (dog.age)

    struct person {
        var name : String
        var email : String
        var phone : String
    }

    var workers = person(name: "Sue", email: "[email protected]", phone: "555-1234")

    let boss = workers.name
    print (boss)

    workers.name = "Bo"
    print (workers.email)
    print (workers.phone)

The first structure defines initial values for its properties so there’s no need for an init function. That’s why you can create a variable with empty parentheses like this:

var dog = pet()

The second structure does not define initial values for its properties, so when you create a variable to represent that structure, you must define initial values.

var workers = person(name: "Sue", email: "[email protected]", phone: "555-1234")

To store data in a structure, you need to specify the variable name representing the structure followed by the property name as shown in Figure 10-5.

9781484212349_Fig10-05.jpg

Figure 10-5. Creating a structure and retrieving data

Using Structures in an OS X Program

By themselves, structures can only hold a limited number of data. For more flexibility, structures are often combined with other data structures such as arrays. That way you can create an array of structures, which you’ll use in this sample program. The program will let you type in multiple names, addresses, and phone numbers, then delete data as well.

  1. From within Xcode choose File image New image Project.
  2. Click Application under the OS X category.
  3. Click Cocoa Application and click the Next button. Xcode now asks for a product name.
  4. Click in the Product Name text field and type StructureProgram.
  5. Make sure the Language pop-up menu displays Swift and that no check boxes are selected.
  6. Click the Next button. Xcode asks where you want to store the project.
  7. Choose a folder to store your project and click the Create button.
  8. Click the MainMenu.xib file in the Project Navigator.
  9. Click on the StructureProgram icon to make the window of the user interface appear.
  10. Choose View image Utilities image Show Object Library to make the Object Library appear in the bottom right corner of the Xcode window.
  11. Drag two Push Buttons, four Labels, and four Text Fields on the user interface and double-click on the push buttons and labels to change the text that appears on them so that it looks similar to Figure 10-6.

9781484212349_Fig10-06.jpg

Figure 10-6. The user interface of the StructureProgram

After you type a name, address, and phone number in the appropriate text fields, the Add button will store this information in a structure, and then store this structure in an array. Each time you add another name, address, and phone number, you’ll be adding another structure to the array while the Total Names text field constantly lists the total number of structures stored in the array.

The View button removes the last item from the array and displays its contents in an alert dialog so you can verify its contents. Then it displays the new total number of structures in the array.

Each text field will need a separate IBOutlet and each push button will need a separate IBAction method, which you’ll need to create by Control-dragging each item from the user interface to your AppDelegate.swift file:

  1. With your user interface still visible in the Xcode window, choose View image Assistant Editor image Show Assistant Editor. The AppDelegate.swift file appears next to the user interface.
  2. Move the mouse over the Add button, hold down the Control key, and drag just above the last curly bracket at the bottom of the AppDelegate.swift file.
  3. Release the mouse and the Control key. A pop-up window appears.
  4. Click in the Connection pop-up menu and choose Action.
  5. Click in the Name text field and type addData.
  6. Click in the Type pop-up menu and choose NSButton. Then click the Connect button.
  7. Move the mouse over the View button, hold down the Control key, and drag just above the last curly bracket at the bottom of the AppDelegate.swift file.
  8. Release the mouse and the Control key. A pop-up window appears.
  9. Click in the Connection pop-up menu and choose Action.
  10. Click in the Name text field and type viewButton.
  11. Click in the Type pop-up menu and choose NSButton. Then click the Connect button. The bottom of the AppDelegate.swift file should look like this:
    @IBAction func viewData(sender: NSButton) {

        }

    @IBAction func addData(sender: NSButton) {
        }
  12. Move the mouse over the Name text field that appears to the right of the Add button, hold down the Control key, and drag below the @IBOutlet line in the AppDelegate.swift file.
  13. Release the mouse and the Control key. A pop-up window appears.
  14. Click in the Name text field and type nameField and click the Connect button.
  15. Move the mouse over the Address text field that appears to the right of the Add button, hold down the Control key, and drag below the @IBOutlet line in the AppDelegate.swift file.
  16. Release the mouse and the Control key. A pop-up window appears.
  17. Click in the Name text field and type addressField and click the Connect button.
  18. Move the mouse over the Phone text field that appears to the right of the Delete button, hold down the Control key, and drag below the @IBOutlet line in the AppDelegate.swift file.
  19. Release the mouse and the Control key. A pop-up window appears.
  20. Click in the Name text field and type phoneField and click the Connect button.
  21. Move the mouse over the Total Names text field that appears to the right of the Query button, hold down the Control key, and drag below the @IBOutlet line in the AppDelegate.swift file.
  22. Release the mouse and the Control key. A pop-up window appears.
  23. Click in the Name text field and type totalField and click the Connect button. You should now have the following IBOutlets that represent all the text fields on your user interface:
    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var nameField: NSTextField!
    @IBOutlet weak var addressField: NSTextField!
    @IBOutlet weak var phoneField: NSTextField!
    @IBOutlet weak var totalField: NSTextField!

At this point we’ve connected the user interface to our Swift code so we can use the IBOutlets to retrieve and display data on the user interface. We’ve also created the IBAction methods so the push buttons on the user interface will make the program actually work. Now we just need to write Swift code to create an initial dictionary and then write more Swift code in each IBAction method to add, delete, or query the dictionary.

  1. Underneath the IBOutlet list in the AppDelegate.swift file, type the following to create a structure that can hold three strings, a name, address, and phone number; a variable that represents the structure; and an array of structures:
        struct person {
        var name = ""
        var address = ""
        var phone = ""
    }

    var employee = person()

    var arrayOfStructures = [person] ()
  2. Modify the addData IBAction method so it takes a value from the Name, Address, and Phone text fields and stores them in the employee structure. Then it stores that structure in an array, displays the total number of array items in the Total Names text field, and clears the Name, Address, and Phone text fields:
    @IBAction func addData(sender: NSButton) {
        employee.name = nameField.stringValue
        employee.address = addressField.stringValue
        employee.phone = phoneField.stringValue
        arrayOfStructures.append(employee)
        totalField.integerValue = arrayOfStructures.count

        nameField.stringValue = ""
        addressField.stringValue = ""
        phoneField.stringValue = ""
    }
  3. Modify the viewData IBAction method so it takes a value from the Key text field and deletes the associated value from the dictionary as follows:
    @IBAction func viewData(sender: NSButton) {
        var myAlert = NSAlert()
        if arrayOfStructures.isEmpty {
            myAlert.messageText = "Array is empty"
            myAlert.runModal()
        } else {
            var personData = person()
            personData = (arrayOfStructures.removeLast())
            totalField.integerValue = arrayOfStructures.count
            myAlert.messageText = personData.name + " " + personData.address + " " + personData.phone
            myAlert.runModal()
        }
    }

The code inside the viewData IBAction method creates an alert dialog. Then it checks if the array is empty. If so, it displays “Array is empty” in the alert dialog.

If the array is not empty, then it removes the last structure stored in the array, displays the new total number of array items in the Total Names text field, and displays the removed structure data in the alert dialog.

The complete contents of the AppDelegate.swift file should look like this:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var nameField: NSTextField!
    @IBOutlet weak var addressField: NSTextField!
    @IBOutlet weak var phoneField: NSTextField!
    @IBOutlet weak var totalField: NSTextField!

    struct person {
        var name = ""
        var address = ""
        var phone = ""
    }

    var employee = person()

    var arrayOfStructures = [person] ()

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

    @IBAction func viewData(sender: NSButton) {
        var myAlert = NSAlert()
        if arrayOfStructures.isEmpty {
            myAlert.messageText = "Array is empty"
            myAlert.runModal()
        } else {
            var personData = person()
            personData = (arrayOfStructures.removeLast())
            totalField.integerValue = arrayOfStructures.count
            myAlert.messageText = personData.name + " " + personData.address + " " + personData.phone
            myAlert.runModal()
        }
    }

    @IBAction func addData(sender: NSButton) {
        employee.name = nameField.stringValue
        employee.address = addressField.stringValue
        employee.phone = phoneField.stringValue
        arrayOfStructures.append(employee)
        totalField.integerValue = arrayOfStructures.count

        nameField.stringValue = ""
        addressField.stringValue = ""
        phoneField.stringValue = ""
    }
}

To see how this program works, follow these steps:

  1. Choose Product image Run. Xcode runs your DictionaryProgram project.
  2. Click in the Name text field and type Bob.
  3. Click in the Address text field and type 123 Main.
  4. Click in the Phone text field and type 555-1234.
  5. Click the Add button. The program shows the number of items in then array (1) in the Total Names text field.
  6. Repeat steps 2 – 5 except type the name Jane, the address 90 Oak Lane, and the phone number of 555-9874. The number 2 appears in the Total Names text field.
  7. Click the View button. An alert dialog appears, displaying Jane, 90 Oak Lane, and 555-9874 as shown in Figure 10-7.

    9781484212349_Fig10-07.jpg

    Figure 10-7. An alert dialog showing the last structure added to the array

  8. Click OK to make the alert dialog go away.
  9. Choose StructureProgram image Quit StructureProgram.

Summary

Tuples are a way to store different data types in a single variable. Like arrays and dictionaries, sets can store lists of the same data type. While arrays are best for storing ordered information and dictionaries are best for fast retrieval of data, sets are best for checking if items belong in a set or not as well as making it easy to manipulate two or more sets.

If you need to store large groups of related data, you could use a tuple, but a tuple gets clumsy with large numbers of data. As an alternative, you can create a structure that lets you define different types of data to hold. Beyond the basic data types (Int, String, Float, and Double), structures also let you hold other data structures such as arrays, dictionaries, or sets. For greater flexibility, you can even put structures in arrays, dictionaries, or sets as well.

In the sample OS X program that you created, you learned how to create a structure and store its data in an array. By now you should be getting comfortable using IBOutlets to display or retrieve data from a user interface, along with creating IBAction methods to make your program actually work.

With tuples, sets, and structures along with arrays and dictionaries, you can combine data structures in a variety of ways to store data in the most flexible way for your particular needs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset