RandomAccessCollection

protocol RandomAccessCollection

A collection that supports efficient random-access index traversal.

Inheritance BidirectionalCollection
Conforming Types AnyRandomAccessCollection, Array, ArraySlice, CollectionOfOne, ContiguousArray, EmptyCollection, Int.Words, Int16.Words, Int32.Words, Int64.Words, Int8.Words, KeyValuePairs, Repeated, UInt.Words, UInt16.Words, UInt32.Words, UInt64.Words, UInt8.Words, Unicode.Scalar.UTF16View, Unicode.Scalar.UTF8View, UnsafeBufferPointer, UnsafeMutableBufferPointer
Associated Types
associatedtype Element
associatedtype Index
associatedtype SubSequence
associatedtype Indices

Random-access collections can move indices any distance and measure the distance between indices in O(1) time. Therefore, the fundamental difference between random-access and bidirectional collections is that operations that depend on index movement or distance measurement offer significantly improved efficiency. For example, a random-access collection's count property is calculated in O(1) instead of requiring iteration of an entire collection.

Conforming to the RandomAccessCollection Protocol

The RandomAccessCollection protocol adds further constraints on the associated Indices and SubSequence types, but otherwise imposes no additional requirements over the BidirectionalCollection protocol. However, in order to meet the complexity guarantees of a random-access collection, either the index for your custom type must conform to the Strideable protocol or you must implement the index(_:offsetBy:) and distance(from:to:) methods with O(1) efficiency.

Instance Variables

var endIndex Required

Declaration

var endIndex: Self.Index
var indices Required

The indices that are valid for subscripting the collection, in ascending order.

A collection's indices property can hold a strong reference to the collection itself, causing the collection to be nonuniquely referenced. If you mutate the collection while iterating over its indices, a strong reference can result in an unexpected copy of the collection. To avoid the unexpected copy, use the index(after:) method starting with startIndex to produce indices instead.

var c = MyFancyCollection([10, 20, 30, 40, 50])
var i = c.startIndex
while i != c.endIndex {
    c[i] /= 5
    i = c.index(after: i)
}
// c == MyFancyCollection([2, 4, 6, 8, 10])

Declaration

var indices: Self.Indices
var startIndex Required

Declaration

var startIndex: Self.Index

Subscripts

subscript subscript(bounds:) Required

Accesses a contiguous subrange of the collection's elements.

The accessed slice uses the same indices for the same elements as the original collection uses. Always use the slice's startIndex property instead of assuming that its indices start at a particular value.

This example demonstrates getting a slice of an array of strings, finding the index of one of the strings in the slice, and then using that index in the original array.

let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"]
let streetsSlice = streets[2 ..< streets.endIndex]
print(streetsSlice)
// Prints "["Channing", "Douglas", "Evarts"]"

let index = streetsSlice.firstIndex(of: "Evarts")    // 4
print(streets[index!])
// Prints "Evarts"
  • Parameter bounds: A range of the collection's indices. The bounds of the range must be valid indices of the collection.

Complexity: O(1)

Declaration

override subscript(bounds: Range<Self.Index>) -> Self.SubSequence
subscript subscript(position:) Required

Declaration

override subscript(position: Self.Index) -> Self.Element

Instance Methods

func distance(from start: Self.Index, to end: Self.Index) -> Int Required

Returns the distance between two indices.

Unless the collection conforms to the BidirectionalCollection protocol, start must be less than or equal to end.

Complexity: O(1)

Declaration

func distance(from start: Self.Index, to end: Self.Index) -> Int
func formIndex(after i: inout Self.Index) Required

Replaces the given index with its successor.

  • Parameter i: A valid index of the collection. i must be less than endIndex.

Declaration

override func formIndex(after i: inout Self.Index)
func formIndex(before i: inout Self.Index) Required

Replaces the given index with its predecessor.

  • Parameter i: A valid index of the collection. i must be greater than startIndex.

Declaration

override func formIndex(before i: inout Self.Index)
func index(_ i: Self.Index, offsetBy distance: Int) -> Self.Index Required

Returns an index that is the specified distance from the given index.

The following example obtains an index advanced four positions from a string's starting index and then prints the character at that position.

let s = "Swift"
let i = s.index(s.startIndex, offsetBy: 4)
print(s[i])
// Prints "t"

The value passed as distance must not offset i beyond the bounds of the collection.

Complexity: O(1)

Declaration

func index(_ i: Self.Index, offsetBy distance: Int) -> Self.Index
func index(_ i: Self.Index, offsetBy distance: Int, limitedBy limit: Self.Index) -> Self.Index? Required

Returns an index that is the specified distance from the given index, unless that distance is beyond a given limiting index.

The following example obtains an index advanced four positions from a string's starting index and then prints the character at that position. The operation doesn't require going beyond the limiting s.endIndex value, so it succeeds.

let s = "Swift"
if let i = s.index(s.startIndex, offsetBy: 4, limitedBy: s.endIndex) {
    print(s[i])
}
// Prints "t"

The next example attempts to retrieve an index six positions from s.startIndex but fails, because that distance is beyond the index passed as limit.

let j = s.index(s.startIndex, offsetBy: 6, limitedBy: s.endIndex)
print(j)
// Prints "nil"

The value passed as distance must not offset i beyond the bounds of the collection, unless the index passed as limit prevents offsetting beyond those bounds.

Complexity: O(1)

Declaration

func index(_ i: Self.Index, offsetBy distance: Int, limitedBy limit: Self.Index) -> Self.Index?
func index(after i: Self.Index) -> Self.Index Required

Returns the position immediately after the given index.

The successor of an index must be well defined. For an index i into a collection c, calling c.index(after: i) returns the same index every time.

  • Parameter i: A valid index of the collection. i must be less than endIndex.

Declaration

override func index(after i: Self.Index) -> Self.Index
func index(before i: Self.Index) -> Self.Index Required

Returns the position immediately before the given index.

  • Parameter i: A valid index of the collection. i must be greater than startIndex.

Declaration

override func index(before i: Self.Index) -> Self.Index

Default Implementations

func difference(from other: C, by areEquivalent: (C.Element, Self.Element) -> Bool) -> CollectionDifference<Self.Element>

Returns the difference needed to produce this collection's ordered elements from the given collection, using the given predicate as an equivalence test.

This function does not infer element moves. If you need to infer moves, call the inferringMoves() method on the resulting difference.

Complexity: Worst case performance is O(n * m), where n is the count of this collection and m is other.count. You can expect faster execution when the collections share many common elements.

Declaration

@available(OSX 10.15, iOS 13, tvOS 13, watchOS 6, *) public func difference<C>(from other: C, by areEquivalent: (C.Element, Self.Element) -> Bool) -> CollectionDifference<Self.Element> where C: BidirectionalCollection, Self.Element == C.Element
func distance(from start: Self.Index, to end: Self.Index) -> Int

Declaration

@inlinable public func distance(from start: Self.Index, to end: Self.Index) -> Int
func dropLast(_ k: Int) -> Self.SubSequence

Returns a subsequence containing all but the specified number of final elements.

If the number of elements to drop exceeds the number of elements in the collection, the result is an empty subsequence.

let numbers = [1, 2, 3, 4, 5]
print(numbers.dropLast(2))
// Prints "[1, 2, 3]"
print(numbers.dropLast(10))
// Prints "[]"
  • Parameter k: The number of elements to drop off the end of the collection. k must be greater than or equal to zero.

Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(k), where k is the number of elements to drop.

Declaration

@inlinable public func dropLast(_ k: Int) -> Self.SubSequence
func formIndex(before i: inout Self.Index)

Replaces the given index with its predecessor.

  • Parameter i: A valid index of the collection. i must be greater than startIndex.

Declaration

@inlinable public func formIndex(before i: inout Self.Index)
func index(_ i: Self.Index, offsetBy distance: Int) -> Self.Index

Declaration

@inlinable public func index(_ i: Self.Index, offsetBy distance: Int) -> Self.Index
func index(_ i: Self.Index, offsetBy distance: Int, limitedBy limit: Self.Index) -> Self.Index?

Declaration

@inlinable public func index(_ i: Self.Index, offsetBy distance: Int, limitedBy limit: Self.Index) -> Self.Index?
var last

The last element of the collection.

If the collection is empty, the value of this property is nil.

let numbers = [10, 20, 30, 40, 50]
if let lastNumber = numbers.last {
    print(lastNumber)
}
// Prints "50"

Complexity: O(1)

Declaration

var last: Self.Element?
func last(where predicate: (Self.Element) throws -> Bool) rethrows -> Self.Element?

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

This example uses the last(where:) method to find the last negative number in an array of integers:

let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
if let lastNegative = numbers.last(where: { $0 < 0 }) {
    print("The last negative number is \(lastNegative).")
}
// Prints "The last negative number is -6."
  • Parameter predicate: A closure that takes an element of the sequence as its argument and returns a Boolean value indicating whether the element is a match.

Complexity: O(n), where n is the length of the collection.

Declaration

@inlinable public func last(where predicate: (Self.Element) throws -> Bool) rethrows -> Self.Element?
func lastIndex(where predicate: (Self.Element) throws -> Bool) rethrows -> Self.Index?

Returns the index of the last element in the collection that matches the given predicate.

You can use the predicate to find an element of a type that doesn't conform to the Equatable protocol or to find an element that matches particular criteria. This example finds the index of the last name that begins with the letter A:

let students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
if let i = students.lastIndex(where: { $0.hasPrefix("A") }) {
    print("\(students[i]) starts with 'A'!")
}
// Prints "Akosua starts with 'A'!"
  • Parameter predicate: A closure that takes an element as its argument and returns a Boolean value that indicates whether the passed element represents a match.

Complexity: O(n), where n is the length of the collection.

Declaration

@inlinable public func lastIndex(where predicate: (Self.Element) throws -> Bool) rethrows -> Self.Index?
func reversed() -> ReversedCollection<Self>

Returns a view presenting the elements of the collection in reverse order.

You can reverse a collection without allocating new space for its elements by calling this reversed() method. A ReversedCollection instance wraps an underlying collection and provides access to its elements in reverse order. This example prints the characters of a string in reverse order:

let word = "Backwards"
for char in word.reversed() {
    print(char, terminator: "")
}
// Prints "sdrawkcaB"

If you need a reversed collection of the same type, you may be able to use the collection's sequence-based or collection-based initializer. For example, to get the reversed version of a string, reverse its characters and initialize a new String instance from the result.

let reversedWord = String(word.reversed())
print(reversedWord)
// Prints "sdrawkcaB"

Complexity: O(1)

Declaration

@inlinable public func reversed() -> ReversedCollection<Self>
func suffix(_ maxLength: Int) -> Self.SubSequence

Returns a subsequence, up to the given maximum length, containing the final elements of the collection.

If the maximum length exceeds the number of elements in the collection, the result contains the entire collection.

let numbers = [1, 2, 3, 4, 5]
print(numbers.suffix(2))
// Prints "[4, 5]"
print(numbers.suffix(10))
// Prints "[1, 2, 3, 4, 5]"
  • Parameter maxLength: The maximum number of elements to return. maxLength must be greater than or equal to zero.

Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(k), where k is equal to maxLength.

Declaration

@inlinable public func suffix(_ maxLength: Int) -> Self.SubSequence