KeyValuePairs

struct KeyValuePairs

A lightweight collection of key-value pairs.

Inheritance ExpressibleByDictionaryLiteral, CustomDebugStringConvertible, CustomStringConvertible, RandomAccessCollection
Associated Types
public typealias Element = (key: Key, value: Value)
public typealias Index = Int

Valid indices consist of the position of every element and a "past the end" position that's not valid for use as a subscript argument.

public typealias Indices = Range<Int>
public typealias SubSequence = Slice<KeyValuePairs<Key, Value>>

This associated type appears as a requirement in the Sequence protocol, but it is restated here with stricter constraints. In a collection, the subsequence should also conform to Collection.

Use a KeyValuePairs instance when you need an ordered collection of key-value pairs and don't require the fast key lookup that the Dictionary type provides. Unlike key-value pairs in a true dictionary, neither the key nor the value of a KeyValuePairs instance must conform to the Hashable protocol.

You initialize a KeyValuePairs instance using a Swift dictionary literal. Besides maintaining the order of the original dictionary literal, KeyValuePairs also allows duplicates keys. For example:

let recordTimes: KeyValuePairs = ["Florence Griffith-Joyner": 10.49,
                                      "Evelyn Ashford": 10.76,
                                      "Evelyn Ashford": 10.79,
                                      "Marlies Gohr": 10.81]
print(recordTimes.first!)
// Prints "("Florence Griffith-Joyner", 10.49)"

Some operations that are efficient on a dictionary are slower when using KeyValuePairs. In particular, to find the value matching a key, you must search through every element of the collection. The call to firstIndex(where:) in the following example must traverse the whole collection to find the element that matches the predicate:

let runner = "Marlies Gohr"
if let index = recordTimes.firstIndex(where: { $0.0 == runner }) {
    let time = recordTimes[index].1
    print("\(runner) set a 100m record of \(time) seconds.")
} else {
    print("\(runner) couldn't be found in the records.")
}
// Prints "Marlies Gohr set a 100m record of 10.81 seconds."

Key-Value Pairs as a Function Parameter

When calling a function with a KeyValuePairs parameter, you can pass a Swift dictionary literal without causing a Dictionary to be created. This capability can be especially important when the order of elements in the literal is significant.

For example, you could create an IntPairs structure that holds a list of two-integer tuples and use an initializer that accepts a KeyValuePairs instance.

struct IntPairs {
    var elements: [(Int, Int)]

    init(_ elements: KeyValuePairs<Int, Int>) {
        self.elements = Array(elements)
    }
}

When you're ready to create a new IntPairs instance, use a dictionary literal as the parameter to the IntPairs initializer. The KeyValuePairs instance preserves the order of the elements as passed.

let pairs = IntPairs([1: 2, 1: 1, 3: 4, 2: 1])
print(pairs.elements)
// Prints "[(1, 2), (1, 1), (3, 4), (2, 1)]"

Initializers

init init(dictionaryLiteral:) Required

Creates a new KeyValuePairs instance from the given dictionary literal.

The order of the key-value pairs is kept intact in the resulting KeyValuePairs instance.

Declaration

@inlinable public init(dictionaryLiteral elements: (Key, Value))

Instance Variables

var debugDescription Required

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

Declaration

var debugDescription: String
var description Required

A string that represents the contents of the dictionary.

Declaration

var description: String
var endIndex Required

The collection's "past the end" position---that is, the position one greater than the last valid subscript argument.

If the KeyValuePairs instance is empty, endIndex is equal to startIndex.

Declaration

var endIndex: KeyValuePairs<Key, Value>.Index
var startIndex Required

The position of the first element in a nonempty collection.

If the KeyValuePairs instance is empty, startIndex is equal to endIndex.

Declaration

var startIndex: KeyValuePairs<Key, Value>.Index

Subscripts

subscript subscript(position:) Required

Accesses the element at the specified position.

  • Parameter position: The position of the element to access. position must be a valid index of the collection that is not equal to the endIndex property.

Declaration

@inlinable public subscript(position: KeyValuePairs<Key, Value>.Index) -> KeyValuePairs<Key, Value>.Element

Instance Methods

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 an array's starting index and then prints the element at that position. The operation doesn't require going beyond the limiting numbers.endIndex value, so it succeeds.

let numbers = [10, 20, 30, 40, 50]
let i = numbers.index(numbers.startIndex, offsetBy: 4)
print(numbers[i])
// Prints "50"

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

let j = numbers.index(numbers.startIndex,
                      offsetBy: 10,
                      limitedBy: numbers.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

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