9
9
//
10
10
//===----------------------------------------------------------------------===//
11
11
12
+ /// A sequence wrapper that leaves out duplicate elements of a base sequence.
13
+ public struct Uniqued < Base: Sequence , Subject: Hashable > {
14
+ /// The base collection.
15
+ @usableFromInline
16
+ internal let base : Base
17
+
18
+ /// The projection function.
19
+ @usableFromInline
20
+ internal let projection : ( Base . Element ) -> Subject
21
+
22
+ @usableFromInline
23
+ internal init ( base: Base , projection: @escaping ( Base . Element ) -> Subject ) {
24
+ self . base = base
25
+ self . projection = projection
26
+ }
27
+ }
28
+
29
+ extension Uniqued : Sequence {
30
+ /// The iterator for a `Uniqued` sequence.
31
+ public struct Iterator : IteratorProtocol {
32
+ @usableFromInline
33
+ internal var base : Base . Iterator
34
+
35
+ @usableFromInline
36
+ internal let projection : ( Base . Element ) -> Subject
37
+
38
+ @usableFromInline
39
+ internal var seen : Set < Subject > = [ ]
40
+
41
+ @usableFromInline
42
+ internal init (
43
+ base: Base . Iterator ,
44
+ projection: @escaping ( Base . Element ) -> Subject
45
+ ) {
46
+ self . base = base
47
+ self . projection = projection
48
+ }
49
+
50
+ @inlinable
51
+ public mutating func next( ) -> Base . Element ? {
52
+ while let element = base. next ( ) {
53
+ if seen. insert ( projection ( element) ) . inserted {
54
+ return element
55
+ }
56
+ }
57
+ return nil
58
+ }
59
+ }
60
+
61
+ @inlinable
62
+ public func makeIterator( ) -> Iterator {
63
+ Iterator ( base: base. makeIterator ( ) , projection: projection)
64
+ }
65
+ }
66
+
67
+ extension Uniqued : LazySequenceProtocol where Base: LazySequenceProtocol { }
68
+
12
69
//===----------------------------------------------------------------------===//
13
70
// uniqued()
14
71
//===----------------------------------------------------------------------===//
15
72
16
73
extension Sequence where Element: Hashable {
17
- /// Returns an array with only the unique elements of this sequence, in the
74
+ /// Returns a sequence with only the unique elements of this sequence, in the
18
75
/// order of the first occurrence of each unique element.
19
76
///
20
77
/// let animals = ["dog", "pig", "cat", "ox", "dog", "cat"]
21
78
/// let uniqued = animals.uniqued()
22
- /// print(uniqued)
79
+ /// print(Array( uniqued) )
23
80
/// // Prints '["dog", "pig", "cat", "ox"]'
24
81
///
25
- /// - Returns: An array with only the unique elements of this sequence.
82
+ /// - Returns: A sequence with only the unique elements of this sequence.
26
83
/// .
27
- /// - Complexity: O(*n*), where *n* is the length of the sequence .
84
+ /// - Complexity: O(1) .
28
85
@inlinable
29
- public func uniqued( ) -> [ Element ] {
30
- uniqued ( on : { $0 } )
86
+ public func uniqued( ) -> Uniqued < Self , Element > {
87
+ Uniqued ( base : self , projection : { $0 } )
31
88
}
32
89
}
33
90
@@ -40,7 +97,7 @@ extension Sequence {
40
97
/// first characters:
41
98
///
42
99
/// let animals = ["dog", "pig", "cat", "ox", "cow", "owl"]
43
- /// let uniqued = animals.uniqued(on: {$0.first})
100
+ /// let uniqued = animals.uniqued(on: { $0.first })
44
101
/// print(uniqued)
45
102
/// // Prints '["dog", "pig", "cat", "ox"]'
46
103
///
@@ -67,3 +124,21 @@ extension Sequence {
67
124
return result
68
125
}
69
126
}
127
+
128
+ //===----------------------------------------------------------------------===//
129
+ // lazy.uniqued()
130
+ //===----------------------------------------------------------------------===//
131
+
132
+ extension LazySequenceProtocol {
133
+ /// Returns a lazy sequence with the unique elements of this sequence (as
134
+ /// determined by the given projection), in the order of the first occurrence
135
+ /// of each unique element.
136
+ ///
137
+ /// - Complexity: O(1).
138
+ @inlinable
139
+ public func uniqued< Subject: Hashable > (
140
+ on projection: @escaping ( Element ) -> Subject
141
+ ) -> Uniqued < Self , Subject > {
142
+ Uniqued ( base: self , projection: projection)
143
+ }
144
+ }
0 commit comments