Swift is a strongly typed language.

Arrays & Sets

Arrays

An array stores an ordered collection of values of the same data type.

var Array1 = [String]()
var Array2: [String] = []
// both create an empty array that contains strings

.count property

var randomExample: [Double] = [1.1, 1.3, 1.42, 0.12]

print(count.randomExample) // returns 4 Int

**.append() Method and += Operator

var gymBadges = ["Boulder", "Cascade"] 
gymBadges.append("Thunder")
gymBadges += ["Rainbow", "Soul"] 
// ["Boulder", "Cascade", "Thunder", "Rainbow", "Soul"]

**.insert() and .remove() Methods

var moon = ["🌖", "🌗", "🌘", "🌑"] 
moon.insert("🌕", at: 0) // ["🌕", "🌖", "🌗", "🌘", "🌑"] 
moon.remove(at: 4) // ["🌕", "🌖", "🌗", "🌘"]

*Iterating Over an Array*

var employees = ["Michael", "Dwight", "Jim", "Pam", "Andy"] 
for person in employees {  
    print(person)
    } 
// Prints: Michael
// Prints: Dwight
// Prints: Jim
// Prints: Pam
// Prints: Andy

*Swift Sets*

var paintings: Set /* IMPORTANT */ = ["The Dream", "The Starry Night", "The False Mirror"]

*Empty Sets*

var team = Set<String>() 
print(team)// Prints: []

*Populated Sets*

var vowels: Set = ["a", "e", "i", "o", "u"]

*.insert()*

To insert a single value into a set, append .insert() to a set and place the new value inside the parentheses ().

var cookieJar: Set = ["Chocolate Chip", "Oatmeal Raisin"]
// Add a new element
cookieJar.insert("Peanut Butter Chip")

*.remove() and .removeAll() Methods*

To remove a single value from a set, append .remove() to a set with the value to be removed placed inside the parentheses ().

To remove every single value from a set at once, append .removeAll() to a set.

var oddNumbers: Set = [1, 2, 3, 5] 
// Remove an existing element
oddNumbers.remove(2) 
// Remove all elements
oddNumbers.removeAll()

*.contains()*

Appending .contains() to an existing set with an item in the parentheses () will return a true or false value that states whether the item exists within the set.

var names: Set = ["Rosa", "Doug", "Waldo"] 
print(names.contains("Lola")) // Prints: false 
if names.contains("Waldo") {  
    print("There's Waldo!")
  } else {  
    print("Where's Waldo?")
}
// Prints: There's Waldo!

*Iterating Over a Set*

for-in loop can be used to iterate over each item in a set.

var recipe: Set = ["Chocolate chips", "Eggs", "Flour", "Sugar"]
for ingredient in recipe {
  print ("Include \\(ingredient) in the recipe.")
}

*.isEmpty Property*

Use the built-in property .isEmpty to check if a set has no values contained in it.

var emptySet = Set<String>()
print(emptySet.isEmpty)  
// Prints: true 
var populatedSet: Set = [1, 2, 3] 
print(populatedSet.isEmpty) 
// Prints: false

*.count Property*

The property .count returns the number of elements contained within a set.

var band: Set = ["Guitar", "Bass", "Drums", "Vocals"]
print("There are \\(band.count) players in the band.")
// Prints: There are 4 players in the band.

*.intersection() Operation*

The .intersection() operation populates a new set of elements with the overlapping elements of two sets.

a intersect b

var setA: Set = ["A", "B", "C", "D"]
var setB: Set = ["C", "D", "E", "F"] 
var setC = setA.intersection(setB)
print(setC)  
// Prints: ["D", "C"]

*.union() Operation*

The .union() operation populates a new set by taking all the values from two sets and combining them.

a U b

var setA: Set = ["A", "B", "C", "D"]
var setB: Set = ["C", "D", "E", "F"]
var setC = setA.union(setB)print(setC) 
// Prints: ["B", "A", "D", "F", "C", "E"]

*.symmetricDifference() Operation*

The .symmetricDifference() operation creates a new set with all the non-overlapping values between two sets.

a’ intersect b’

var setA: Set = ["A", "B", "C", "D"]
var setB: Set = ["C", "D", "E", "F"]
var setC = setA.symmetricDifference(setB)
print(setC) 
// Prints: ["B", "E", "F", "A"]

*.subtracting() Operation*

The .subtracting() operation removes the values of one second set from another set and stores the remaining values in a new set.

a

var setA: Set = ["A", "B", "C", "D"]
var setB: Set = ["C", "D"]
var setC = setA.subtracting(setB)
print(setC)
// Prints: ["B", "A"]

Functions

func washCar() -> Void {
  print("Soap")
  print("Scrub")
  print("Rinse")
  print("Dry")
}

washCar()
// Output: Soap \\n Scrub \\n Rinse \\n Dry

Returning

Parameters

func convertFracToDec(numerator: Double, denominator: Double) -> Double {
  return numerator / denominator
} 

let decimal = convertFracToDec(numerator: 1.0, denominator: 2.0)
print(decimal) // Prints: 0.5

Parameter Types

Structures (not Classes)

struct Apple {
    var price = Double
    var sale = Bool
    init(Double: price, Bool: sale)
        price = self.price
        sale = self.sale
    func exampleMethod -> String {
        print("Hello World")
    }

Diff between classes and structures in Swift

Classes

Also can be applied in Python

Class Inheritance

To create a class that inherits from another, we put the name of the class we’re inheriting from (superclass) after the name of the class we’re creating (subclass), like so:

class Subclass: Superclass {}

The subclass will inherit the properties and functions and literally everything from the superclass. However, subclasses can have special properties that are more special that superclasses do not have.

Overriding Methods

override func name(parameter) {

}

// Using data types:
class Student {
  var name: String
  var year: Int
  var gpa: Double
  var honors: Bool
  init()
}

// Using default property values:
class Student {
  var name = ""
  var year = 0
  var gpa = 0.0
  var honors = false
}
    

class Fruit {
  var hasSeeds = true
  var color: String
  init(color: String) {
    self.color = color
  }
}
let apple = Fruit(color: "red")

In Swift, a struct is a value type that can hold a collection of related properties and methods. A class is a reference type that can also hold a collection of related properties and methods. An object is an instance of a class, and it contains the actual data and behavior of the class.

struct Point {
    var x: Double
    var y: Double
}

class Shape {
    var color: String
    
    init(color: String) {
        self.color = color
    }
    
    func draw() {
        print("Drawing a shape with color: \(color)")
    }
}

let point1 = Point(x: 1.0, y: 2.0)
var point2 = point1
point2.x = 3.0
print(point1.x) // 1.0
print(point2.x) // 3.0

let shape1 = Shape(color: "red")
var shape2 = shape1
shape2.color = "blue"
print(shape1.color) // red
print(shape2.color) // blue

In this example, the Point struct is a value type that holds the coordinates of a point. The Shape class is a reference type that holds the color of a shape and has a draw method. When a Point instance is assigned to another variable, a copy of the Point is created and used, so changing the value of the copied Point does not affect the original Point. When a Shape instance is assigned to another variable, a reference to the Shape is used, so changing the value of the copied Shape also changes the value of the original Shape.

In reference to my previous question, is an object also an instance of a struct?

In Swift, an object is an instance of a class, not a struct. A struct is a value type, whereas a class is a reference type, so the two are not interchangeable.

An instance of a struct is created using the struct's name and the initializer syntax, for example:

let point = Point(x: 1.0, y: 2.0)

An instance of a class is created using the class keyword and the initializer syntax, for example:

let shape = Shape(color: "red")

In both cases, the resulting value is an instance of the specified type. However, the instance of a struct is a value type, while the instance of a class is a reference type. This means that the struct instance is a copy of the original struct, while the class instance is a reference to the original class.

Explain what are mutating functions in the context of Swift

struct Person { var name: Stringmutating funcchangeName(newName: String) { name = newName } }

In Swift, mutating functions are useful for modifying the state of an object in place, without the need to create a new object. However, they can also cause confusion and make code harder to reason about, so they should be used with care.