diff --git a/base/set.jl b/base/set.jl index b6c9765a0b6cc..a04bc106ed1da 100644 --- a/base/set.jl +++ b/base/set.jl @@ -728,3 +728,30 @@ function _replace!(new::Callable, t::Set{T}, ::AbstractSet, count::Int) where {T end t end + +### replace for tuples + +function _replace(f::Callable, t::Tuple, count::Int) + if count == 0 || isempty(t) + t + else + x = f(t[1]) + (x, _replace(f, tail(t), count - !==(x, t[1]))...) + end +end + +replace(f::Callable, t::Tuple; count::Integer=typemax(Int)) = + _replace(f, t, check_count(count)) + +function _replace(t::Tuple, count::Int, old_new::Tuple{Vararg{Pair}}) + _replace(t, count) do x + @_inline_meta + for o_n in old_new + isequal(first(o_n), x) && return last(o_n) + end + return x + end +end + +replace(t::Tuple, old_new::Pair...; count::Integer=typemax(Int)) = + _replace(t, check_count(count), old_new) diff --git a/test/sets.jl b/test/sets.jl index 82f2a3b0aab6f..46854dae957c6 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -586,11 +586,14 @@ end @testset "replace! & replace" begin a = [1, 2, 3, 1] @test replace(x -> iseven(x) ? 2x : x, a) == [1, 4, 3, 1] + @test replace(x -> iseven(x) ? 2x : x, Tuple(a)) === (1, 4, 3, 1) @test replace!(x -> iseven(x) ? 2x : x, a) === a @test a == [1, 4, 3, 1] @test replace(a, 1=>0) == [0, 4, 3, 0] + @test replace(Tuple(a), 1=>0) === (0, 4, 3, 0) for count = (1, 0x1, big(1)) @test replace(a, 1=>0, count=count) == [0, 4, 3, 1] + @test replace(Tuple(a), 1=>0, count=count) === (0, 4, 3, 1) end @test replace!(a, 1=>2) === a @test a == [2, 4, 3, 2] @@ -615,6 +618,7 @@ end for count = (0, 0x0, big(0)) # count == 0 --> no replacements @test replace([1, 2], 1=>0, 2=>0; count) == [1, 2] + @test replace((1, 2), 1=>0, 2=>0; count) === (1, 2) for dict = (Dict(1=>2, 2=>3), IdDict(1=>2, 2=>3)) @test replace(dict, (1=>2) => (1=>3); count) == dict end @@ -668,7 +672,9 @@ end # test that isequal is used @test replace([NaN, 1.0], NaN=>0.0) == [0.0, 1.0] + @test replace((NaN, 1.0), NaN=>0.0) === (0.0, 1.0) @test replace([1, missing], missing=>0) == [1, 0] + @test replace((1, missing), missing=>0) === (1, 0) end @testset "⊆, ⊊, ⊈, ⊇, ⊋, ⊉, <, <=, issetequal" begin