# Set

An unordered collection of unique elements.

`@frozen struct Set<Element> where Element : Hashable`

## Overview

You use a set instead of an array when you need to test efficiently for membership and you aren’t concerned with the order of the elements in the collection, or when you need to ensure that each element appears only once in a collection.

You can create a set with any element type that conforms to the `Hashable`

protocol. By default, most types in the standard library are hashable, including strings, numeric and Boolean types, enumeration cases without associated values, and even sets themselves.

Swift makes it as easy to create a new set as to create a new array. Simply assign an array literal to a variable or constant with the `Set`

type specified.

```
let ingredients: Set = ["cocoa beans", "sugar", "cocoa butter", "salt"]
if ingredients.contains("sugar") {
print("No thanks, too sweet.")
}
// Prints "No thanks, too sweet."
```

## Set Operations

Sets provide a suite of mathematical set operations. For example, you can efficiently test a set for membership of an element or check its intersection with another set:

Use the

`contains(_:)`

method to test whether a set contains a specific element.Use the “equal to” operator (

`==`

) to test whether two sets contain the same elements.Use the

`isSubset(of:)`

method to test whether a set contains all the elements of another set or sequence.Use the

`isSuperset(of:)`

method to test whether all elements of a set are contained in another set or sequence.Use the

`isStrictSubset(of:)`

and`isStrictSuperset(of:)`

methods to test whether a set is a subset or superset of, but not equal to, another set.Use the

`isDisjoint(with:)`

method to test whether a set has any elements in common with another set.

You can also combine, exclude, or subtract the elements of two sets:

Use the

`union(_:)`

method to create a new set with the elements of a set and another set or sequence.Use the

`intersection(_:)`

method to create a new set with only the elements common to a set and another set or sequence.Use the

`symmetricDifference(_:)`

method to create a new set with the elements that are in either a set or another set or sequence, but not in both.Use the

`subtracting(_:)`

method to create a new set with the elements of a set that are not also in another set or sequence.

You can modify a set in place by using these methods’ mutating counterparts: `formUnion(_:)`

, `formIntersection(_:)`

, `formSymmetricDifference(_:)`

, and `subtract(_:)`

.

Set operations are not limited to use with other sets. Instead, you can perform set operations with another set, an array, or any other sequence type.

```
var primes: Set = [2, 3, 5, 7]
// Tests whether primes is a subset of a Range<Int>
print(primes.isSubset(of: 0..<10))
// Prints "true"
// Performs an intersection with an Array<Int>
let favoriteNumbers = [5, 7, 15, 21]
print(primes.intersection(favoriteNumbers))
// Prints "[5, 7]"
```

## Sequence and Collection Operations

In addition to the `Set`

type’s set operations, you can use any nonmutating sequence or collection methods with a set.

```
if primes.isEmpty {
print("No primes!")
} else {
print("We have \(primes.count) primes.")
}
// Prints "We have 4 primes."
let primesSum = primes.reduce(0, +)
// 'primesSum' == 17
let primeStrings = primes.sorted().map(String.init)
// 'primeStrings' == ["2", "3", "5", "7"]
```

You can iterate through a set’s unordered elements with a `for`

-`in`

loop.

```
for number in primes {
print(number)
}
// Prints "5"
// Prints "7"
// Prints "2"
// Prints "3"
```

Many sequence and collection operations return an array or a type-erasing collection wrapper instead of a set. To restore efficient set operations, create a new set from the result.

```
let primesStrings = primes.map(String.init)
// 'primesStrings' is of type Array<String>
let primesStringsSet = Set(primes.map(String.init))
// 'primesStringsSet' is of type Set<String>
```

## Bridging Between Set and NSSet

You can bridge between `Set`

and `NSSet`

using the `as`

operator. For bridging to be possible, the `Element`

type of a set must be a class, an `@objc`

protocol (a protocol imported from Objective-C or marked with the `@objc`

attribute), or a type that bridges to a Foundation type.

Bridging from `Set`

to `NSSet`

always takes O(1) time and space. When the set’s `Element`

type is neither a class nor an `@objc`

protocol, any required bridging of elements occurs at the first access of each element, so the first operation that uses the contents of the set (for example, a membership test) can take O(*n*).

Bridging from `NSSet`

to `Set`

first calls the `copy(with:)`

method (`- copyWithZone:`

in Objective-C) on the set to get an immutable copy and then performs additional Swift bookkeeping work that takes O(1) time. For instances of `NSSet`

that are already immutable, `copy(with:)`

returns the same set in constant time; otherwise, the copying performance is unspecified. The instances of `NSSet`

and `Set`

share buffer using the same copy-on-write optimization that is used when two instances of `Set`

share buffer.