@@ -167,15 +167,39 @@ julia> unique(x -> x^2, [1, -1, 3, -3, 4])
167
167
"""
168
168
function unique (f, C)
169
169
out = Vector {eltype(C)} ()
170
- seen = Set ()
171
- for x in C
170
+
171
+ s = iterate (C)
172
+ if s === nothing
173
+ return out
174
+ end
175
+ (x, i) = s
176
+ y = f (x)
177
+ seen = Set {typeof(y)} ()
178
+ push! (seen, y)
179
+ push! (out, x)
180
+
181
+ return _unique! (f, out, C, seen, i)
182
+ end
183
+
184
+ function _unique! (f, out:: AbstractVector , C, seen:: Set , i)
185
+ s = iterate (C, i)
186
+ while s != = nothing
187
+ (x, i) = s
172
188
y = f (x)
173
- if ! in (y, seen)
174
- push! (seen, y)
189
+ if y ∉ seen
175
190
push! (out, x)
191
+ if y isa eltype (seen)
192
+ push! (seen, y)
193
+ else
194
+ seen2 = convert (Set{promote_typejoin (eltype (seen), typeof (y))}, seen)
195
+ push! (seen2, y)
196
+ return _unique! (f, out, C, seen2, i)
197
+ end
176
198
end
199
+ s = iterate (C, i)
177
200
end
178
- out
201
+
202
+ return out
179
203
end
180
204
181
205
"""
@@ -205,22 +229,39 @@ julia> unique!(iseven, [2, 3, 5, 7, 9])
205
229
```
206
230
"""
207
231
function unique! (f, A:: AbstractVector )
208
- seen = Set ()
209
- idxs = eachindex (A)
210
- y = iterate (idxs)
211
- count = 0
212
- for x in A
213
- t = f (x)
214
- if t ∉ seen
215
- push! (seen,t)
232
+ if length (A) <= 1
233
+ return A
234
+ end
235
+
236
+ i = firstindex (A)
237
+ x = @inbounds A[i]
238
+ y = f (x)
239
+ seen = Set {typeof(y)} ()
240
+ push! (seen, y)
241
+ return _unique! (f, A, seen, 1 , i+ 1 )
242
+ end
243
+
244
+ function _unique! (f, A:: AbstractVector , seen:: Set , count:: Integer , i:: Integer )
245
+ while i <= lastindex (A)
246
+ x = @inbounds A[i]
247
+ y = f (x)
248
+ if y ∉ seen
216
249
count += 1
217
- A[y[1 ]] = x
218
- y = iterate (idxs, y[2 ])
250
+ @inbounds A[count] = x
251
+ if y isa eltype (seen)
252
+ push! (seen, y)
253
+ else
254
+ seen2 = convert (Set{promote_typejoin (eltype (seen), typeof (y))}, seen)
255
+ push! (seen2, y)
256
+ return _unique! (f, A, seen2, count, i+ 1 )
257
+ end
219
258
end
259
+ i += 1
220
260
end
221
- resize! (A, count)
261
+ return resize! (A, count)
222
262
end
223
263
264
+
224
265
# If A is not grouped, then we will need to keep track of all of the elements that we have
225
266
# seen so far.
226
267
_unique! (A:: AbstractVector ) = unique! (identity, A:: AbstractVector )
0 commit comments