-
Notifications
You must be signed in to change notification settings - Fork 441
/
Copy pathIndexed.swift
117 lines (101 loc) · 3.31 KB
/
Indexed.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Algorithms open source project
//
// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
/// A collection wrapper that iterates over the indices and elements of a
/// collection together.
public struct IndexedCollection<Base: Collection> {
/// The base collection.
@usableFromInline
internal let base: Base
@inlinable
internal init(base: Base) {
self.base = base
}
}
extension IndexedCollection: Collection {
/// The element type for an `IndexedCollection` collection.
public typealias Element = (index: Base.Index, element: Base.Element)
@inlinable
public var startIndex: Base.Index {
base.startIndex
}
@inlinable
public var endIndex: Base.Index {
base.endIndex
}
@inlinable
public subscript(position: Base.Index) -> Element {
(index: position, element: base[position])
}
@inlinable
public func index(after i: Base.Index) -> Base.Index {
base.index(after: i)
}
@inlinable
public func index(_ i: Base.Index, offsetBy distance: Int) -> Base.Index {
base.index(i, offsetBy: distance)
}
@inlinable
public func index(
_ i: Base.Index,
offsetBy distance: Int,
limitedBy limit: Base.Index
) -> Base.Index? {
base.index(i, offsetBy: distance, limitedBy: limit)
}
@inlinable
public func distance(from start: Base.Index, to end: Base.Index) -> Int {
base.distance(from: start, to: end)
}
@inlinable
public var indices: Base.Indices {
base.indices
}
}
extension IndexedCollection: BidirectionalCollection
where Base: BidirectionalCollection
{
@inlinable
public func index(before i: Base.Index) -> Base.Index {
base.index(before: i)
}
}
extension IndexedCollection: RandomAccessCollection
where Base: RandomAccessCollection {}
extension IndexedCollection: LazySequenceProtocol, LazyCollectionProtocol
where Base: LazySequenceProtocol {}
//===----------------------------------------------------------------------===//
// indexed()
//===----------------------------------------------------------------------===//
extension Collection {
/// Returns a collection of pairs *(i, x)*, where *i* represents an index of
/// the collection, and *x* represents an element.
///
/// The `indexed()` method is similar to the standard library's `enumerated()`
/// method, but provides the index with each element instead of a zero-based
/// counter.
///
/// This example iterates over the indices and elements of a set, building an
/// array consisting of indices of names with five or fewer letters.
///
/// let names: Set = ["Sofia", "Camilla", "Martina", "Mateo", "Nicolás"]
/// var shorterIndices: [Set<String>.Index] = []
/// for (i, name) in names.indexed() {
/// if name.count <= 5 {
/// shorterIndices.append(i)
/// }
/// }
///
/// - Returns: A collection of paired indices and elements of this collection.
@inlinable
public func indexed() -> IndexedCollection<Self> {
IndexedCollection(base: self)
}
}