@@ -41,16 +41,16 @@ public struct IdentifiedArray<ID, Element>: MutableCollection, RandomAccessColle
4141where ID: Hashable {
4242 /// A key path to a value that identifies an element.
4343 public let id : KeyPath < Element , ID >
44-
44+
4545 /// A raw array of each element's identifier.
4646 public private( set) var ids : [ ID ]
47-
47+
4848 /// A raw array of the underlying elements.
4949 public var elements : [ Element ] { Array ( self ) }
50-
50+
5151 // TODO: Support multiple elements with the same identifier but different data.
5252 private var dictionary : [ ID : Element ]
53-
53+
5454 /// Initializes an identified array with a sequence of elements and a key
5555 /// path to an element's identifier.
5656 ///
@@ -60,92 +60,92 @@ where ID: Hashable {
6060 public init < S> ( _ elements: S , id: KeyPath < Element , ID > )
6161 where S: Sequence , S. Element == Element {
6262 self . id = id
63-
63+
6464 let idsAndElements = elements. map { ( id: $0 [ keyPath: id] , element: $0) }
6565 self . ids = idsAndElements. map { $0. id }
6666 self . dictionary = Dictionary ( idsAndElements, uniquingKeysWith: { $1 } )
6767 }
68-
68+
6969 /// Initializes an empty identified array with a key path to an element's
7070 /// identifier.
7171 ///
7272 /// - Parameter id: A key path to a value that identifies an element.
7373 public init ( id: KeyPath < Element , ID > ) {
7474 self . init ( [ ] , id: id)
7575 }
76-
76+
7777 public var startIndex : Int { self . ids. startIndex }
7878 public var endIndex : Int { self . ids. endIndex }
79-
79+
8080 public func index( after i: Int ) -> Int {
8181 self . ids. index ( after: i)
8282 }
83-
83+
8484 public func index( before i: Int ) -> Int {
8585 self . ids. index ( before: i)
8686 }
87-
87+
8888 public subscript( position: Int ) -> Element {
8989 // NB: `_read` crashes Xcode Preview compilation.
9090 get { self . dictionary [ self . ids [ position] ] ! }
9191 _modify { yield & self . dictionary [ self . ids [ position] ] ! }
9292 }
93-
93+
9494 #if DEBUG
95- /// Direct access to an element by its identifier.
96- ///
97- /// - Parameter id: The identifier of element to access. Must be a valid identifier for an
98- /// element of the array and will _not_ insert elements that are not already in the array, or
99- /// remove elements when passed `nil`. Use `append` or `insert(_:at:)` to insert elements. Use
100- /// `remove(id:)` to remove an element by its identifier.
101- /// - Returns: The element.
102- public subscript( id id: ID ) -> Element ? {
103- get { self . dictionary [ id] }
104- set {
105- if newValue != nil && self . dictionary [ id] == nil {
106- fatalError (
107- """
108- Can't update element with identifier \( id) because no such element exists in the array.
109-
110- If you are trying to insert an element into the array, use the " append " or " insert " \
111- methods.
112- """
113- )
114- }
115- if newValue == nil {
116- fatalError (
117- """
118- Can't update element with identifier \( id) with nil.
119-
120- If you are trying to remove an element from the array, use the " remove(id:) method. "
121- """
122- )
95+ /// Direct access to an element by its identifier.
96+ ///
97+ /// - Parameter id: The identifier of element to access. Must be a valid identifier for an
98+ /// element of the array and will _not_ insert elements that are not already in the array, or
99+ /// remove elements when passed `nil`. Use `append` or `insert(_:at:)` to insert elements. Use
100+ /// `remove(id:)` to remove an element by its identifier.
101+ /// - Returns: The element.
102+ public subscript( id id: ID ) -> Element ? {
103+ get { self . dictionary [ id] }
104+ set {
105+ if newValue != nil && self . dictionary [ id] == nil {
106+ fatalError (
107+ """
108+ Can't update element with identifier \( id) because no such element exists in the array.
109+
110+ If you are trying to insert an element into the array, use the " append " or " insert " \
111+ methods.
112+ """
113+ )
114+ }
115+ if newValue == nil {
116+ fatalError (
117+ """
118+ Can't update element with identifier \( id) with nil.
119+
120+ If you are trying to remove an element from the array, use the " remove(id:) method. "
121+ """
122+ )
123+ }
124+ self . dictionary [ id] = newValue
123125 }
124- self . dictionary [ id] = newValue
125126 }
126- }
127127 #else
128- public subscript( id id: ID ) -> Element ? {
129- // NB: `_read` crashes Xcode Preview compilation.
130- get { self . dictionary [ id] }
131- _modify { yield & self . dictionary [ id] }
132- }
128+ public subscript( id id: ID ) -> Element ? {
129+ // NB: `_read` crashes Xcode Preview compilation.
130+ get { self . dictionary [ id] }
131+ _modify { yield & self . dictionary [ id] }
132+ }
133133 #endif
134-
134+
135135 public mutating func insert( _ newElement: Element , at i: Int ) {
136136 let id = newElement [ keyPath: self . id]
137137 self . dictionary [ id] = newElement
138138 self . ids. insert ( id, at: i)
139139 }
140-
140+
141141 public mutating func insert< C> (
142142 contentsOf newElements: C , at i: Int
143143 ) where C: Collection , Element == C . Element {
144144 for newElement in newElements. reversed ( ) {
145145 self . insert ( newElement, at: i)
146146 }
147147 }
148-
148+
149149 /// Removes and returns the element with the specified identifier.
150150 ///
151151 /// - Parameter id: The identifier of the element to remove.
@@ -158,12 +158,12 @@ where ID: Hashable {
158158 self . ids. removeAll ( where: { $0 == id } )
159159 return element!
160160 }
161-
161+
162162 @discardableResult
163163 public mutating func remove( at position: Int ) -> Element {
164164 self . remove ( id: self . ids. remove ( at: position) )
165165 }
166-
166+
167167 public mutating func removeAll( where shouldBeRemoved: ( Element ) throws -> Bool ) rethrows {
168168 var ids : [ ID ] = [ ]
169169 for (index, id) in zip ( self . ids. indices, self . ids) . reversed ( ) {
@@ -176,34 +176,34 @@ where ID: Hashable {
176176 self . dictionary [ id] = nil
177177 }
178178 }
179-
179+
180180 public mutating func remove( atOffsets offsets: IndexSet ) {
181181 for offset in offsets. reversed ( ) {
182182 _ = self . remove ( at: offset)
183183 }
184184 }
185-
185+
186186 #if canImport(SwiftUI)
187- public mutating func move( fromOffsets source: IndexSet , toOffset destination: Int ) {
188- self . ids. move ( fromOffsets: source, toOffset: destination)
189- }
187+ public mutating func move( fromOffsets source: IndexSet , toOffset destination: Int ) {
188+ self . ids. move ( fromOffsets: source, toOffset: destination)
189+ }
190190 #endif
191-
191+
192192 public mutating func sort( by areInIncreasingOrder: ( Element , Element ) throws -> Bool ) rethrows {
193193 try self . ids. sort {
194194 try areInIncreasingOrder ( self . dictionary [ $0] !, self . dictionary [ $1] !)
195195 }
196196 }
197-
197+
198198 public mutating func shuffle< T> ( using generator: inout T ) where T: RandomNumberGenerator {
199199 ids. shuffle ( using: & generator)
200200 }
201-
201+
202202 public mutating func shuffle( ) {
203203 var rng = SystemRandomNumberGenerator ( )
204204 self . shuffle ( using: & rng)
205205 }
206-
206+
207207 public mutating func reverse( ) {
208208 ids. reverse ( )
209209 }
@@ -278,17 +278,17 @@ where Element: Identifiable, ID == Element.ID {
278278 public init ( ) {
279279 self . init ( [ ] , id: \. id)
280280 }
281-
281+
282282 public mutating func replaceSubrange< C, R> ( _ subrange: R , with newElements: C )
283283 where C: Collection , R: RangeExpression , Element == C . Element , Index == R . Bound {
284284 let replacingIds = self . ids [ subrange]
285285 let newIds = newElements. map { $0. id }
286286 ids. replaceSubrange ( subrange, with: newIds)
287-
287+
288288 for element in newElements {
289289 self . dictionary [ element. id] = element
290290 }
291-
291+
292292 for id in replacingIds where !self . ids. contains ( id) {
293293 self . dictionary [ id] = nil
294294 }
0 commit comments