diff --git a/NEWS.md b/NEWS.md index d27714f3f4231..bbd4f44b6517e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -168,6 +168,10 @@ This section lists changes that do not have deprecation warnings. way as `^(A::Integer, p::Integer)`. This means, for instance, that `[1 1; 0 1]^big(1)` will return a `Matrix{BigInt}` instead of a `Matrix{Int}` ([#23366]). + * The element type of the input is now preserved in `unique`. Previously the element type + of the output was shrunk to fit the union of the type of each element in the input. + ([#22696]) + Library improvements -------------------- @@ -1204,6 +1208,7 @@ Command-line option changes [#22588]: https://github.com/JuliaLang/julia/issues/22588 [#22605]: https://github.com/JuliaLang/julia/issues/22605 [#22666]: https://github.com/JuliaLang/julia/issues/22666 +[#22696]: https://github.com/JuliaLang/julia/issues/22696 [#22703]: https://github.com/JuliaLang/julia/issues/22703 [#22712]: https://github.com/JuliaLang/julia/issues/22712 [#22718]: https://github.com/JuliaLang/julia/issues/22718 diff --git a/base/set.jl b/base/set.jl index f5ced5e45d779..86f1e93b889b4 100644 --- a/base/set.jl +++ b/base/set.jl @@ -240,7 +240,8 @@ const ⊆ = issubset Return an array containing only the unique elements of collection `itr`, as determined by [`isequal`](@ref), in the order that the first of each -set of equivalent elements originally appears. +set of equivalent elements originally appears. The element type of the +input is preserved. # Examples ```jldoctest @@ -249,6 +250,11 @@ julia> unique([1, 2, 6, 2]) 1 2 6 + +julia> unique(Real[1, 1.0, 2]) +2-element Array{Real,1}: + 1 + 2 ``` """ function unique(itr) @@ -260,7 +266,7 @@ function unique(itr) return out end x, i = next(itr, i) - if !isleaftype(T) + if !isleaftype(T) && iteratoreltype(itr) == EltypeUnknown() S = typeof(x) return _unique_from(itr, S[x], Set{S}((x,)), i) end diff --git a/test/core.jl b/test/core.jl index adf0778660968..08c3986562915 100644 --- a/test/core.jl +++ b/test/core.jl @@ -5382,7 +5382,8 @@ for U in unboxedunions # deleteat! F = Base.uniontypes(U)[2] A = U[rand(F(1):F(len)) for i = 1:len] - deleteat!(A, map(Int, sort!(unique(A[1:4])))) + # The 2-arg `unique` method works around #22688 + deleteat!(A, map(Int, sort!(unique(identity, A[1:4])))) A = U[initvalue2(F2) for i = 1:len] deleteat!(A, 1:2) @test length(A) == len - 2 diff --git a/test/sets.jl b/test/sets.jl index 3efb3804be7bf..7041e475295b1 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -233,6 +233,8 @@ u = unique([1,1,2]) # issue 20105 @test @inferred(unique(x for x in 1:1)) == [1] @test unique(x for x in Any[1,1.0])::Vector{Real} == [1] +@test unique(x for x in Real[1,1.0])::Vector{Real} == [1] +@test unique(Integer[1,1,2])::Vector{Integer} == [1,2] # unique! @testset "unique!" begin