Set and Tuple

Introduction

Welcome to Lesson 9 of The Swift Fundamentals. There are two objectives. The first is to learn how to group a list of items with sets. The second is to work with various types within a single variable/constant with tuples.

Problem

  1. I’d love to eliminate duplicated items: sets
  2. I’d love to combine all kinds of types: tuples

Introducing Sets

A set stores values of the same type in a collection with no defined ordering and no duplicated elements.

Multiple Ways to Create Arrays

Before we create sets in Swift, let’s review multiple ways to create an array.

Remember, Array is just a generic struct.

  1. var arrayOne: [Double] = [] // Most Common
  2. var arrayTwo = [Double]()
  3. var arrayThree: Array<Double> = []
  4. var arrayFour: Array<Double> = Array()
  5. var arrayFive = Array([1123.08, 234.23])
  6. var arraySix = Array(1...100)
  7. var arraySeven = Array(repeatElement("Bob", count: 10))

Remember, Set is just a generic struct.

Multiple Ways to Create Sets

Set in Swift looks similar to Array.

  1. var setOne: Set = [1, 2, 3, 4, 5]
  2. var setTwo: Set<String> = ["Bob", "Bobby", "Bob the Developer"]
  3. var emptySet = Set<String>()

Built-In Set Methods

Similar to Array, Set contains default methods and properties.

  1. emptySet.insert("Bob")
  2. emptySet.contains("Bob") // true
  3. emptySet.remove("Bob")

Create Two Arrays

You may convert Array to Set, or vice versa. In this example, let us convert Array to Set. First, create two arrays filled with odd and even numbers.

  1. var oddNumbers: [Int] = []
  2. var evenNumbers: [Int] = []
  3. for number in 1...50 {
  4. if number % 2 == 0 {
  5. evenNumbers.append(number)
  6. } else {
  7. oddNumbers.append(number)
  8. }
  9. }

Ternary Operator

You may use ternary operator as an alternative to achieve the same result above. You will learn more in 1011_intro_operators

  1. for number in 1...50 {
  2. (number % 2 == 0) ? evenNumber.append(number) : oddNumber.append(number)
  3. }

Check

  1. oddNumbers // [1, 3, 5, 7, 9, ...]
  2. evenNumbers // [2, 4, 6, 8, 10, ...]

Convert Array to Set

  1. var oddNumberSet = Set(oddNumbers)
  2. let evenNumberSet = Set(evenNumbers)

oddNumberSet and evenNumberSet no longer has defined order.

Built-In Set Methods

Set provides methods to work with multiple sets.

Built-in Set methods

Union

  1. oddNumberSet.union(evenNumberSet)

Symmetric Difference

  1. oddNumberSet.symmetricDifference(evenNumberSet)

Intersection

  1. oddNumberSet.intersection(evenNumberSet)

Subtract

  1. oddNumberSet.subtract(evenNumberSet)
  2. var numberSet = Set([1, 2, 3])
  3. let secondNumberSet = Set([1, 2])
  4. numberSet.subtract(secondNumberSet)
  5. print(numberSet) // {3}

Subtract mutates oddNumberSet. Therefore, the oddNumberSet instance must be var rather than let. You can predict whether a method is mutating or not based on the naming guide below.

Swift Naming Guide

Mutating Non-Mutating
verb adjective
array.append() array.sorted()
array.sort() array.appending

Sort

Since sets do not provide any order, sets must be converted to an array type to be sorted. There is a built-in method called, sorted().

  1. let sortedArray = evenNumberSet.sorted()
  2. print(sortedArray) // [2, 4, 6, ...]

Functional Programming

The sorted() is flexible.

  1. let sortedArrayFromHighToLow = evenNumberSet.sorted { $0 > $1 }
  2. print(sortedArrayFromHighToLow) // [100, 98, 96, ...]

In this course, you are not going to learn how sorted() is constructed. However, if you are interested in learning more about Functional/Reactive Programming with RxSwift and MVVM, you can be on the mailing list for my upcoming courses.

Practical Usage of Set

  • Finding unique letters and unique visitors
  • Any game logic (Up to your imagination)

Introducing Tuples

You may combine multiple types of value in a single let or var.

  1. let firstScore = (name: "Bob", score: 9)

You may access elements through calling the index similar to Array

  1. firstScore.0 // "Bob"
  2. firstScore.1 // 9

You may also access the elements through the labels.

  1. firstScore.name // "Bob"
  2. firstScore.score // 9

However, you don’t have to specify the argument labels.

  1. let secondScore = ("Rob", 10)
  2. secondScore.0
  3. secondScore.1

Practical Usage

This is your past.

  1. let httpFailure: [Any] = [401, "Fail"]

You no longer have to upcast to Any.

  1. let httpSuccess = (code: 200, description: "success")
  2. httpSuccess.code

Bonus Tips

You created multiple instances in a single line.

  1. // Okay
  2. var dog = "dog", cat = "cat"
  3. print(dog)

Instead, you may use tuple

  1. // Better
  2. var (x, y, z) = (1, 2, 3)
  3. print(x)
  4. print(y)

You may convert an array into a tuple that contains index and element through the enumerated() method.

  1. var shoppingList = ["Eggs", "Milk", "Rice"]
  2. for (index, value) in shoppingList.enumerated() {
  3. print(index, value)
  4. }

Source Code

1009_set_tuple.playground

Reference

Swift API Design Guidelines

Conclusion

To recap, Set is used to group non-duplicate items with no order. Tuple is used to group all kinds of types with the order you define. Second, you’ve learned how to identify mutating vs non-mutating methods based on the naming guide. Make sure you follow the same principle in your codebase as well. Don’t get too caught up with Functional Programming. I know it sounds cool. You will get a taste of it in chapter 3, Intro to Functional Swift.

In the next lesson, you will learn how to write modular and beautiful code with extension.