99//
1010//===----------------------------------------------------------------------===//
1111
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+
1269//===----------------------------------------------------------------------===//
1370// uniqued()
1471//===----------------------------------------------------------------------===//
1572
1673extension 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
1875 /// order of the first occurrence of each unique element.
1976 ///
2077 /// let animals = ["dog", "pig", "cat", "ox", "dog", "cat"]
2178 /// let uniqued = animals.uniqued()
22- /// print(uniqued)
79+ /// print(Array( uniqued) )
2380 /// // Prints '["dog", "pig", "cat", "ox"]'
2481 ///
25- /// - Returns: An array with only the unique elements of this sequence.
82+ /// - Returns: A sequence with only the unique elements of this sequence.
2683 /// .
27- /// - Complexity: O(*n*), where *n* is the length of the sequence .
84+ /// - Complexity: O(1) .
2885 @inlinable
29- public func uniqued( ) -> [ Element ] {
30- uniqued ( on : { $0 } )
86+ public func uniqued( ) -> Uniqued < Self , Element > {
87+ Uniqued ( base : self , projection : { $0 } )
3188 }
3289}
3390
@@ -40,7 +97,7 @@ extension Sequence {
4097 /// first characters:
4198 ///
4299 /// let animals = ["dog", "pig", "cat", "ox", "cow", "owl"]
43- /// let uniqued = animals.uniqued(on: {$0.first})
100+ /// let uniqued = animals.uniqued(on: { $0.first })
44101 /// print(uniqued)
45102 /// // Prints '["dog", "pig", "cat", "ox"]'
46103 ///
@@ -67,3 +124,21 @@ extension Sequence {
67124 return result
68125 }
69126}
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