Swift Set
- Swift Sets are a data structure type that holds unique values of the same type in an unordered fashion.
- Set can only take types that conform to the Hashable protocol.
- Sets store the values based on the hashValue() thanks to the hashable protocol. Hence the access time is constant in sets.
- A hashValue is an Integer such that it is the same for all objects that compare equally. If a == b is true then a.hashValue == b.hashValue must be true.
How is Set different from Array?
- Sets store unique values. Arrays can store repeated.
- Sets are unordered. Printing a set won’t give the same order as it was defined. Arrays are ordered.
- Sets store values based on hash values. Arrays don’t.
- Sets have a constant lookup time thanks to storing by hash values. Arrays don’t. Hence Sets are faster than Array.
How are Sets different from Dictionaries?
Both are unordered, but dictionaries can have the same values in two different keys. Sets have unique values always. Let’s launch our Swift Playground in XCode and get started.
Declaring a set
import Foundation var emptySet = Set<String>() emptySet = [] var filledSet: Set<Int> = [3,1,2] var typeInferredSet: Set = ["Red", "Yellow", "Green"] print(filledSet) print(emptySet) print(typeInferredSet)
To declare a set we must use the keyword Set followed by the type inside <>. Swift can infer the type as well from the values set on the right-hand side.
The above code prints the following in the console.
[quote font=”georgia”][3, 2, 1]
[]
[“Yellow”, “Red”, “Green”][/quote]
Inserting and Removing Elements from a Set
We can insert and remove elements in a set in the following manner
import Foundation let typeInferredSet: Set = ["Red", "Yellow", "Green"] //typeInferredSet.insert("Wednesday") //compilation error. Cannot insert in immutable sets var emptySet = Set<String>() emptySet.insert("One") emptySet.insert("Two") emptySet.insert("One") //emptySet.insert(3) //Error Referencing instance method 'insert' on 'Set' requires the types 'String' typeInferredSet.contains("Red") //returns true var filledSet: Set<Int> = [3,1,2] var x = filledSet.remove(2) var y = filledSet.remove(0) let storeIndex = filledSet.firstIndex(of: 1) if let unwrapped = storeIndex { filledSet.remove(at: unwrapped) } filledSet.removeAll() //removes all the elements print("Empty set: \(emptySet) x is: \(x ?? -1) y is: \(y ?? -1)")
- We cannot insert elements in Sets with let constant.
- The removed elements can be retrieved in a var/let variable.
- The removed elements are returned as Optionals.
- If the removed element doesn’t exist, it returns nil which is wrapped in the optional.
- Duplicate elements that are inserted get ignored.
- Inserting an element with a different type would give a compilation error.
- To remove an element using its index we need to pass the Set<Type>.Index of the element into remove(at:). For this, we need to retrieve the index using index(of:) and pass the value by optional unwrapping using if let statement
- x ?? checks whether the Optional is null or not, if it is, it prints the value on the right of ?? else it prints the value from the optional after unwrapping.
Find an element in a set
contains() method checks whether the given element is present in the set and returns a boolean value.
The capacity of the set
The count property returns the number of elements present in the set. isEmpty checks whether the set is empty or not and returns a boolean.
import Foundation var filledSet: Set<Int> = [3,1,2] filledSet.removeAll() print(filledSet.count) //returns 0 print(filledSet.isEmpty) //returns true
Creating a Set from an Array
We can create a set from an array using the following syntax
import Foundation let intSet = Set([5,1,4,6]) let myArray = ["Monday","Tuesday"] let anotherSet = Set(myArray) let sequenceSet = Set<Int>(1...5) print(sequenceSet) // [5, 2, 3, 1, 4]
[quote font=”georgia”]We can create a set from an array by passing the array inside the Set(). We can also create a set using Ranges in Swift.[/quote]
Iterating over a set
We can iterate over a set in the following manner using a for-in loop.
import Foundation var newSet: Set<String> = ["www.","balututorial",".com"] for words in newSet{ print(words) }
[quote font=”georgia”]Printing a set won’t give the same order as it was defined[/quote]
Sorting the set
Use the sorted() method to keep the set in an ordered way.
import Foundation var newSet: Set<Int> = [5,4,1,2,3] print(newSet) for words in newSet.sorted() { print(words) }
The above code prints 1 to 5. It sorts the set in ascending order by default.
Swift Set Operations
Swift Set operations are useful for comparing two data sets. The following diagrams illustrate the commonly used operations.
Ref: https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html
Subset and Superset
import Foundation var setA : Set<String> = ["A","B","C","D","E"] var setB : Set<String> = ["C","D","E"] var setC : Set<String> = ["A","B","C","D","E"] setB.isSubset(of: setA) //true setB.isStrictSubset(of: setA) //true setC.isSubset(of: setA) //true setC.isStrictSubset(of: setA) //false setA.isSuperset(of: setB) //true setA.isStrictSuperset(of: setB) //true
- isStrictSubset() returns true if the set is a subset of the passed in superset but NOT an exact copy.
- isStrictSuperset() returns true if the set is a superset of the passed in subset but NOT an exact copy.
Disjoint and union
Two sets are disjointed if no elements are common. Union of two sets joins both of them (ignoring duplicates).
import Foundation var setA: Set<String> = ["A","B","C","D","E"] var setB: Set<String> = ["C","D","E"] var setC: Set<String> = ["A","B","C","D","E"] var setD: Set<String> = ["A","F"] setD.isDisjoint(with: setB) //true setD.isDisjoint(with: setA) //false var unionSet = setD.union(setA) // {"B", "A", "F", "C", "D} var inter = setD.intersection(setA) // {"A"}
- the union needs to store the result in a new variable.
- intersection method would get the common elements from both the sets.
- setA.substract(setB) would remove the elements from A that are there in B too and return a new set. setA won’t be changed unless we reassign the new set as setA only.