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 **s****equence** and backwards, if we wanna create a set from an array, we can use the set initializer that accepts a **s****equence** as an input parameter

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