Skip to content

Commit b46c74c

Browse files
ararslanStefanKarpinski
authored andcommitted
Preserve the input element type in unique (#23208)
Previously the element type of the output was the smallest type that would fit the union of the input's individual element types. Now the output has an identical element type to the input. Fixes #22696.
1 parent 2406b6e commit b46c74c

File tree

4 files changed

+17
-3
lines changed

4 files changed

+17
-3
lines changed

NEWS.md

+5
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ This section lists changes that do not have deprecation warnings.
168168
way as `^(A::Integer, p::Integer)`. This means, for instance, that `[1 1; 0 1]^big(1)`
169169
will return a `Matrix{BigInt}` instead of a `Matrix{Int}` ([#23366]).
170170

171+
* The element type of the input is now preserved in `unique`. Previously the element type
172+
of the output was shrunk to fit the union of the type of each element in the input.
173+
([#22696])
174+
171175
Library improvements
172176
--------------------
173177

@@ -1204,6 +1208,7 @@ Command-line option changes
12041208
[#22588]: https://github.com/JuliaLang/julia/issues/22588
12051209
[#22605]: https://github.com/JuliaLang/julia/issues/22605
12061210
[#22666]: https://github.com/JuliaLang/julia/issues/22666
1211+
[#22696]: https://github.com/JuliaLang/julia/issues/22696
12071212
[#22703]: https://github.com/JuliaLang/julia/issues/22703
12081213
[#22712]: https://github.com/JuliaLang/julia/issues/22712
12091214
[#22718]: https://github.com/JuliaLang/julia/issues/22718

base/set.jl

+8-2
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ const ⊆ = issubset
240240
241241
Return an array containing only the unique elements of collection `itr`,
242242
as determined by [`isequal`](@ref), in the order that the first of each
243-
set of equivalent elements originally appears.
243+
set of equivalent elements originally appears. The element type of the
244+
input is preserved.
244245
245246
# Examples
246247
```jldoctest
@@ -249,6 +250,11 @@ julia> unique([1, 2, 6, 2])
249250
1
250251
2
251252
6
253+
254+
julia> unique(Real[1, 1.0, 2])
255+
2-element Array{Real,1}:
256+
1
257+
2
252258
```
253259
"""
254260
function unique(itr)
@@ -260,7 +266,7 @@ function unique(itr)
260266
return out
261267
end
262268
x, i = next(itr, i)
263-
if !isleaftype(T)
269+
if !isleaftype(T) && iteratoreltype(itr) == EltypeUnknown()
264270
S = typeof(x)
265271
return _unique_from(itr, S[x], Set{S}((x,)), i)
266272
end

test/core.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -5382,7 +5382,8 @@ for U in unboxedunions
53825382
# deleteat!
53835383
F = Base.uniontypes(U)[2]
53845384
A = U[rand(F(1):F(len)) for i = 1:len]
5385-
deleteat!(A, map(Int, sort!(unique(A[1:4]))))
5385+
# The 2-arg `unique` method works around #22688
5386+
deleteat!(A, map(Int, sort!(unique(identity, A[1:4]))))
53865387
A = U[initvalue2(F2) for i = 1:len]
53875388
deleteat!(A, 1:2)
53885389
@test length(A) == len - 2

test/sets.jl

+2
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ u = unique([1,1,2])
233233
# issue 20105
234234
@test @inferred(unique(x for x in 1:1)) == [1]
235235
@test unique(x for x in Any[1,1.0])::Vector{Real} == [1]
236+
@test unique(x for x in Real[1,1.0])::Vector{Real} == [1]
237+
@test unique(Integer[1,1,2])::Vector{Integer} == [1,2]
236238

237239
# unique!
238240
@testset "unique!" begin

0 commit comments

Comments
 (0)