Generic Structure

Set

An unordered collection of unique elements.

Declaration

@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 morePrimes = primes.union([11, 13, 17, 19])

let laterPrimes = morePrimes.filter { $0 > 10 }
// 'laterPrimes' is of type Array<Int>

let laterPrimesSet = Set(morePrimes.filter { $0 > 10 })
// 'laterPrimesSet' is of type Set<Int>

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.

Topics

Creating a Set

In addition to using an array literal, you can also create a set using these initializers.

init()

Creates an empty set.

init(minimumCapacity: Int)

Creates an empty set with preallocated space for at least the specified number of elements.

init<S>(S)

Creates a new set from a finite sequence of items.

init<Source>(Source)

Creates a new set from a finite sequence of items.

Inspecting a Set

var isEmpty: Bool

A Boolean value that indicates whether the set is empty.

var count: Int

The number of elements in the set.

var capacity: Int

The total number of elements that the set can contain without allocating new storage.

Testing for Membership

func contains(Element) -> Bool

Returns a Boolean value that indicates whether the given element exists in the set.

Removing Elements

func filter((Element) -> Bool) -> Set<Element>

Returns a new set containing the elements of the set that satisfy the given predicate.

func remove(Element) -> Element?

Removes the specified element from the set.

func removeFirst() -> Element

Removes the first element of the set.

func remove(at: Set<Element>.Index) -> Element

Removes the element at the given index of the set.

func removeAll(keepingCapacity: Bool)

Removes all members from the set.

Combining Sets

func union<S>(S) -> Set<Element>

Returns a new set with the elements of both this set and the given sequence.

func formUnion<S>(S)

Inserts the elements of the given sequence into the set.

func intersection(Set<Element>) -> Set<Element>

Returns a new set with the elements that are common to both this set and the given sequence.

func intersection<S>(S) -> Set<Element>

Returns a new set with the elements that are common to both this set and the given sequence.

func formIntersection<S>(S)

Removes the elements of the set that aren’t also in the given sequence.

func symmetricDifference<S>(S) -> Set<Element>

Returns a new set with the elements that are either in this set or in the given sequence, but not in both.

func formSymmetricDifference(Set<Element>)

Removes the elements of the set that are also in the given sequence and adds the members of the sequence that are not already in the set.

func formSymmetricDifference<S>(S)

Replace this set with the elements contained in this set or the given set, but not both.

func subtract(Set<Element>)

Removes the elements of the given set from this set.

func subtract<S>(S)

Removes the elements of the given sequence from the set.

func subtracting(Set<Element>) -> Set<Element>

Returns a new set containing the elements of this set that do not occur in the given set.

func subtracting<S>(S) -> Set<Element>

Returns a new set containing the elements of this set that do not occur in the given sequence.

Comparing Sets

static func == (Set<Element>, Set<Element>) -> Bool

Returns a Boolean value indicating whether two sets have equal elements.

static func != (Set<Element>, Set<Element>) -> Bool

Returns a Boolean value indicating whether two values are not equal.

func isSubset(of: Set<Element>) -> Bool

Returns a Boolean value that indicates whether this set is a subset of the given set.

func isSubset<S>(of: S) -> Bool

Returns a Boolean value that indicates whether the set is a subset of the given sequence.

func isStrictSubset(of: Set<Element>) -> Bool

Returns a Boolean value that indicates whether the set is a strict subset of the given sequence.

func isStrictSubset<S>(of: S) -> Bool

Returns a Boolean value that indicates whether the set is a strict subset of the given sequence.

func isSuperset(of: Set<Element>) -> Bool

Returns a Boolean value that indicates whether this set is a superset of the given set.

func isSuperset<S>(of: S) -> Bool

Returns a Boolean value that indicates whether the set is a superset of the given sequence.

func isStrictSuperset(of: Set<Element>) -> Bool

Returns a Boolean value that indicates whether the set is a strict superset of the given sequence.

func isStrictSuperset<S>(of: S) -> Bool

Returns a Boolean value that indicates whether the set is a strict superset of the given sequence.

func isDisjoint(with: Set<Element>) -> Bool

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

func isDisjoint<S>(with: S) -> Bool

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

Accessing Individual Elements

var first: Element?

The first element of the collection.

func randomElement() -> Element?

Returns a random element of the collection.

func randomElement<T>(using: inout T) -> Element?

Returns a random element of the collection, using the given generator as a source for randomness.

Finding Elements

subscript(Set<Element>.Index) -> Element

Accesses the member at the given position.

func contains(where: (Element) -> Bool) -> Bool

Returns a Boolean value indicating whether the sequence contains an element that satisfies the given predicate.

func allSatisfy((Element) -> Bool) -> Bool

Returns a Boolean value indicating whether every element of a sequence satisfies a given predicate.

func first(where: (Element) -> Bool) -> Element?

Returns the first element of the sequence that satisfies the given predicate.

func firstIndex(of: Element) -> Set<Element>.Index?

Returns the index of the given element in the set, or nil if the element is not a member of the set.

func firstIndex(where: (Element) -> Bool) -> Set<Element>.Index?

Returns the first index in which an element of the collection satisfies the given predicate.

func index(of: Element) -> Set<Element>.Index?

Returns the first index where the specified value appears in the collection.

Deprecated
func min() -> Element?

Returns the minimum element in the sequence.

func min(by: (Element, Element) -> Bool) -> Element?

Returns the minimum element in the sequence, using the given predicate as the comparison between elements.

func max() -> Element?

Returns the maximum element in the sequence.

func max(by: (Element, Element) -> Bool) -> Element?

Returns the maximum element in the sequence, using the given predicate as the comparison between elements.

Transforming a Set

func map<T>((Element) -> T) -> [T]

Returns an array containing the results of mapping the given closure over the sequence’s elements.

func compactMap<ElementOfResult>((Element) -> ElementOfResult?) -> [ElementOfResult]

Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.

func flatMap<SegmentOfResult>((Element) -> SegmentOfResult) -> [SegmentOfResult.Element]

Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.

func reduce<Result>(Result, (Result, Element) -> Result) -> Result

Returns the result of combining the elements of the sequence using the given closure.

func reduce<Result>(into: Result, (inout Result, Element) -> ()) -> Result

Returns the result of combining the elements of the sequence using the given closure.

func sorted() -> [Element]

Returns the elements of the sequence, sorted.

func sorted(by: (Element, Element) -> Bool) -> [Element]

Returns the elements of the sequence, sorted using the given predicate as the comparison between elements.

func shuffled() -> [Element]

Returns the elements of the sequence, shuffled.

func shuffled<T>(using: inout T) -> [Element]

Returns the elements of the sequence, shuffled using the given generator as a source for randomness.

var lazy: LazySequence<Set<Element>>

A sequence containing the same elements as this sequence, but on which some operations, such as map and filter, are implemented lazily.

Iterating over a Set

func enumerated() -> EnumeratedSequence<Set<Element>>

Returns a sequence of pairs (n, x), where n represents a consecutive integer starting at zero and x represents an element of the sequence.

func forEach((Element) -> Void)

Calls the given closure on each element in the sequence in the same order as a for-in loop.

func makeIterator() -> Set<Element>.Iterator

Returns an iterator over the members of the set.

var underestimatedCount: Int

A value less than or equal to the number of elements in the collection.

Performing Collection Operations

Order Dependent Operations on Set

Perform order-dependent operations common to all collections, as implemented for Set.

Encoding and Decoding

func encode(to: Encoder)

Encodes the elements of this set into the given encoder in an unkeyed container.

init(from: Decoder)

Creates a new set by decoding from the given decoder.

Describing a Set

func hash(into: inout Hasher)

Hashes the essential components of this value by feeding them into the given hasher.

var description: String

A string that represents the contents of the set.

var debugDescription: String

A string that represents the contents of the set, suitable for debugging.

var customMirror: Mirror

A mirror that reflects the set.

Reference Types

Use bridged reference types when you need reference semantics or Foundation-specific behavior.

class NSSet

An object representing a static, unordered, uniquing collection, for use instead of a Set constant in cases that require reference semantics.

class NSMutableSet

An object representing a dynamic, unordered, uniquing collection, for use instead of a Set variable in cases that require reference semantics.

Supporting Types

struct Set.Index

The position of an element in a set.

struct Set.Iterator

An iterator over the members of a Set<Element>.

Infrequently Used Functionality

init(arrayLiteral: Element...)

Creates a set containing the elements of the given array literal.

func withContiguousStorageIfAvailable<R>((UnsafeBufferPointer<Element>) -> R) -> R?

Call body(p), where p is a pointer to the collection’s contiguous storage. If no such storage exists, it is first created. If the collection does not support an internal representation in a form of contiguous storage, body is not called and nil is returned.

Type Aliases

typealias Set.ArrayLiteralElement

The type of the elements of an array literal.

typealias Set.Indices

A type that represents the indices that are valid for subscripting the collection, in ascending order.

typealias Set.SubSequence

A sequence that represents a contiguous subrange of the collection’s elements.

Initializers

init(_immutableCocoaSet: AnyObject)

Private initializer used for bridging.

Instance Properties

var hashValue: Int

The hash value.

Instance Methods

func index(where: (Element) -> Bool) -> Set<Element>.Index?

Returns the first index in which an element of the collection satisfies the given predicate.

Deprecated

Relationships

See Also

Basic Collections

struct Array

An ordered, random-access collection.

struct Dictionary

A collection whose elements are key-value pairs.