Skip to content

Commit 7ea37ab

Browse files
authored
setdiff preserves eltype (#59439)
1 parent 8052b91 commit 7ea37ab

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

base/abstractset.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ intersect!(s::AbstractSet, itr) =
201201
setdiff(s, itrs...)
202202
203203
Construct the set of elements in `s` but not in any of the iterables in `itrs`.
204-
Maintain order with arrays.
204+
Maintain order with arrays. The result will have the same element type as `s`.
205205
206206
See also [`setdiff!`](@ref), [`union`](@ref) and [`intersect`](@ref).
207207
@@ -211,6 +211,10 @@ julia> setdiff([1,2,3], [3,4,5])
211211
2-element Vector{Int64}:
212212
1
213213
2
214+
215+
julia> setdiff([1,2,3], [1.0, 2.0])
216+
1-element Vector{Int64}:
217+
3
214218
```
215219
"""
216220
setdiff(s::AbstractSet, itrs...) = setdiff!(copymutable(s), itrs...)

base/array.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,14 +3133,17 @@ setdiff!( v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
31333133

31343134
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
31353135

3136-
function _shrink(shrinker!::F, itr, itrs) where F
3136+
function intersect(itr, itrs...)
31373137
T = promote_eltype(itr, itrs...)
3138-
keep = shrinker!(Set{T}(itr), itrs...)
3138+
keep = intersect!(Set{T}(itr), itrs...)
31393139
vectorfilter(T, _shrink_filter!(keep), itr)
31403140
end
31413141

3142-
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
3143-
setdiff( itr, itrs...) = _shrink(setdiff!, itr, itrs)
3142+
function setdiff(itr, itrs...)
3143+
T = eltype(itr)
3144+
keep = setdiff!(Set{T}(itr), itrs...)
3145+
vectorfilter(T, _shrink_filter!(keep), itr)
3146+
end
31443147

31453148
function intersect(v::AbstractVector, r::AbstractRange)
31463149
T = promote_eltype(v, r)

test/arrayops.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,18 @@ end
12461246
@test setdiff((1, 2), (3, 2)) == [1]
12471247
@test symdiff((1, 2), (3, 2)) == [1, 3]
12481248
end
1249+
1250+
@testset "setdiff preserves element type of first argument" begin
1251+
@test setdiff([1, 2, 3], [1.0, 2.0]) isa Vector{Int}
1252+
@test setdiff([1.0, 2.0, 3.0], [1, 2]) isa Vector{Float64}
1253+
@test setdiff(['a', 'b', 'c'], [98]) isa Vector{Char}
1254+
@test setdiff([1, 2], [1.0, 2.0]) isa Vector{Int}
1255+
end
1256+
@testset "intersect promotes element types of arguments" begin
1257+
@test intersect([1, 2, 3], [1.0, 2.0]) isa Vector{Float64}
1258+
@test intersect([1.0, 2.0, 3.0], [1, 2]) isa Vector{Float64}
1259+
@test intersect(['a', 'b', 'c'], Int[]) isa Vector{Any}
1260+
end
12491261
end
12501262

12511263
@testset "mapslices" begin

0 commit comments

Comments
 (0)