OptionSet

protocol OptionSet

A type that presents a mathematical set interface to a bit set.

Inheritance RawRepresentable, SetAlgebra
Associated Types
associatedtype Element

To inherit all the default implementations from the OptionSet protocol, the Element type must be Self, the default.

You use the OptionSet protocol to represent bitset types, where individual bits represent members of a set. Adopting this protocol in your custom types lets you perform set-related operations such as membership tests, unions, and intersections on those types. What's more, when implemented using specific criteria, adoption of this protocol requires no extra work on your part.

When creating an option set, include a rawValue property in your type declaration. For your type to automatically receive default implementations for set-related operations, the rawValue property must be of a type that conforms to the FixedWidthInteger protocol, such as Int or UInt8. Next, create unique options as static properties of your custom type using unique powers of two (1, 2, 4, 8, 16, and so forth) for each individual property's raw value so that each property can be represented by a single bit of the type's raw value.

For example, consider a custom type called ShippingOptions that is an option set of the possible ways to ship a customer's purchase. ShippingOptions includes a rawValue property of type Int that stores the bit mask of available shipping options. The static members nextDay, secondDay, priority, and standard are unique, individual options.

struct ShippingOptions: OptionSet {
    let rawValue: Int

    static let nextDay    = ShippingOptions(rawValue: 1 << 0)
    static let secondDay  = ShippingOptions(rawValue: 1 << 1)
    static let priority   = ShippingOptions(rawValue: 1 << 2)
    static let standard   = ShippingOptions(rawValue: 1 << 3)

    static let express: ShippingOptions = [.nextDay, .secondDay]
    static let all: ShippingOptions = [.express, .priority, .standard]
}

Declare additional preconfigured option set values as static properties initialized with an array literal containing other option values. In the example, because the express static property is assigned an array literal with the nextDay and secondDay options, it will contain those two elements.

Using an Option Set Type

When you need to create an instance of an option set, assign one of the type's static members to your variable or constant. Alternatively, to create an option set instance with multiple members, assign an array literal with multiple static members of the option set. To create an empty instance, assign an empty array literal to your variable.

let singleOption: ShippingOptions = .priority
let multipleOptions: ShippingOptions = [.nextDay, .secondDay, .priority]
let noOptions: ShippingOptions = []

Use set-related operations to check for membership and to add or remove members from an instance of your custom option set type. The following example shows how you can determine free shipping options based on a customer's purchase price:

let purchasePrice = 87.55

var freeOptions: ShippingOptions = []
if purchasePrice > 50 {
    freeOptions.insert(.priority)
}

if freeOptions.contains(.priority) {
    print("You've earned free priority shipping!")
} else {
    print("Add more to your cart for free priority shipping!")
}
// Prints "You've earned free priority shipping!"

Initializers

init init(rawValue:) Required

Creates a new option set from the given raw value.

This initializer always succeeds, even if the value passed as rawValue exceeds the static properties declared as part of the option set. This example creates an instance of ShippingOptions with a raw value beyond the highest element, with a bit mask that effectively contains all the declared static members.

let extraOptions = ShippingOptions(rawValue: 255)
print(extraOptions.isStrictSuperset(of: .all))
// Prints "true"
  • Parameter rawValue: The raw value of the option set to create. Each bit of rawValue potentially represents an element of the option set, though raw values may include bits that are not defined as distinct values of the OptionSet type.

Declaration

init(rawValue: Self.RawValue)

Default Implementations

init init(_:)

Creates a new set from a finite sequence of items.

Use this initializer to create a new set from an existing sequence, like an array or a range:

let validIndices = Set(0..<7).subtracting([2, 4, 5])
print(validIndices)
// Prints "[6, 0, 1, 3]"
  • Parameter sequence: The elements to use as members of the new set.

Declaration

@inlinable public init<S>(_ sequence: S) where S: Sequence, Self.Element == S.Element
func isDisjoint(with other: Self) -> Bool

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

In the following example, the employees set is disjoint with the visitors set because no name appears in both sets.

let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let visitors: Set = ["Marcia", "Nathaniel", "Olivia"]
print(employees.isDisjoint(with: visitors))
// Prints "true"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public func isDisjoint(with other: Self) -> Bool
var isEmpty

A Boolean value that indicates whether the set has no elements.

Declaration

var isEmpty: Bool
func isStrictSubset(of other: Self) -> Bool

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

Set A is a strict subset of another set B if every member of A is also a member of B and B contains at least one element that is not a member of A.

let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let attendees: Set = ["Alicia", "Bethany", "Diana"]
print(attendees.isStrictSubset(of: employees))
// Prints "true"

// A set is never a strict subset of itself:
print(attendees.isStrictSubset(of: attendees))
// Prints "false"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public func isStrictSubset(of other: Self) -> Bool
func isStrictSuperset(of other: Self) -> Bool

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

Set A is a strict superset of another set B if every member of B is also a member of A and A contains at least one element that is not a member of B.

let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let attendees: Set = ["Alicia", "Bethany", "Diana"]
print(employees.isStrictSuperset(of: attendees))
// Prints "true"

// A set is never a strict superset of itself:
print(employees.isStrictSuperset(of: employees))
// Prints "false"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public func isStrictSuperset(of other: Self) -> Bool
func isSubset(of other: Self) -> Bool

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

Set A is a subset of another set B if every member of A is also a member of B.

let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let attendees: Set = ["Alicia", "Bethany", "Diana"]
print(attendees.isSubset(of: employees))
// Prints "true"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public func isSubset(of other: Self) -> Bool
func isSuperset(of other: Self) -> Bool

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

Set A is a superset of another set B if every member of B is also a member of A.

let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let attendees: Set = ["Alicia", "Bethany", "Diana"]
print(employees.isSuperset(of: attendees))
// Prints "true"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public func isSuperset(of other: Self) -> Bool
func subtract(_ other: Self)

Removes the elements of the given set from this set.

In the following example, the elements of the employees set that are also members of the neighbors set are removed. In particular, the names "Bethany" and "Eric" are removed from employees.

var employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
employees.subtract(neighbors)
print(employees)
// Prints "["Diana", "Chris", "Alicia"]"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public mutating func subtract(_ other: Self)
func subtracting(_ other: Self) -> Self

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

In the following example, the nonNeighbors set is made up of the elements of the employees set that are not elements of neighbors:

let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
let nonNeighbors = employees.subtract(neighbors)
print(nonNeighbors)
// Prints "["Diana", "Chris", "Alicia"]"
  • Parameter other: A set of the same type as the current set.

Declaration

@inlinable public func subtracting(_ other: Self) -> Self