IOS developer based in barcelona.

Using Set in Swift

Set, an unordered collection of unique elements, is one of the most important collections types in Swift (array, dictionary and set)

You use set instead of an array when:
1. You aren't concerned about the order of the elements (order does not matter)
2. You need to ensure that every element only appears once (no duplicated values)
3. You need to test efficiently for membership

Imagine that you have a list of different names, group by friends, family, coworkers and school. You can operate with many mathematical operations that set give us for free.

let friends: Set = ["Alberto", "John", "Rachel"]
let family: Set = ["Alberto", "Rachel", "John"]
let coworkers: Set = ["Daniel", "Laura", "Carmen", "Alberto", "John", "Rachel"]
let school: Set = ["Peter", "Harry"]

The above set collections are initialized with array literal because set conforms to ExpressibleByArrayLiteral protocol, so you can create sets like arrays.


Let's see all the operations offered using sets

Contains

Returns a boolean value that indicates whether the given element exists in the set. In our example, the friends set contains Alberto

friends.contains("Alberto") // true

Equal (==)

Returns a boolean value that indicates whether the two sets contain the same elements. The sets can have different element order. In our case, friends and family have different order.

friends == family // true

isSubset(of:)

Returns a boolean and checks whether a set contains all the elements of another set or sequence. All the elements in friends are also in the coworkers set

friends.isSubset(of: coworkers) // true
friends.isSubset(of: friends) // true

isSuperset(of:)

Returns a boolean value and checks whether all elements of a set are contained in another set or sequence. The coworkers set contains all the elements in friends set.

coworkers.isSuperset(of: friends) // true

isStrictSubset(of:) and isStrictSuperset(of:)

Check the same as isSubset(of:) and isSuperset(of:), BUT if they are not equal, I mean, whether the set A has the same elements of set B It would return false

friends.isStrictSubset(of: coworkers) // true
friends.isStrictSubset(of: friends) // false

isDisjoint(with:)

Returns a Boolean value that indicates whether this set has no members in common with the given set

coworkers.isDisjoint(with: school) // true
coworkers.isDisjoint(with: coworkers) // false

Let's see more set examples

Union

Returns a new set with the values from set A and set B, in our case, the new set has the elements from coworkers and school

coworkers.union(school) // {"Harry", "Peter", "Daniel", "Laura", "Carmen", "John", "Alberto", "Rachel"}

Intersection

Returns a new set with the elements that are common in set A and set B, in our case, the repeated names in bot sets are Alberto, Rachel and John

coworkers.intersection(friends) // {"Alberto", "Rachel", "John"}

symmetricDifference

Returns a new set with the elements that are not common in set A and set B. So, it's the opposite as the intersection

coworkers.symmetricDifference(friends) // {"Laura", "Carmen", "Daniel"}

subtracting

Returns a new set containing the element of set A that don't exist in set B.

coworkers.subtracting(friends) // {"Laura", "Carmen", "Daniel"}

Notes

The above functions return new sets, but we can use the mutating function to change the current set instead of creating a new one, to do that, we need to udpate our set variables to var, instead of let.

var mutatingCoworkers = coworkers
mutatingCoworkers.formUnion(friends)
mutatingCoworkers.formIntersection(friends)
mutatingCoworkers.formSymmetricDifference(friends)
mutatingCoworkers.subtracting(friends)

Another important aspect to discuss, we can create a set from an array and backwards. For example,  creating an array from one of our previous set, it's super easy:

let array = Array(coworkers)
type(of: array) // Array.Type

Why is it so easy? because the swift standard library has an array initializer that creates and array from a sequence and backwards, if we wanna create a set from an array, we can use the set initializer that accepts a sequence as an input parameter

let set = Set(array)
type(of: set) // Set.Type

DateFormatter to display relative dates: today, yesterday, etc

Create NSCollectionView programatically without Storyboards