Mutating a Set during iteration

Is it safe to iterate over a set and mutate it in process?
Say, I have a Set{Int64} and want to replace all negative values in it by their absolute values. Is it OK to

for x in set_of_ints
    if x < 0
        pop!(set_of_ints, x)
        push!(set_of_ints, -x)
    end
end

?

The answer is that it often works, but not always. Also it is bad practice to mutate a collection while iterating and should be avoided. You can generate counter examples like this:

using Test
for _ in 1:1000
    set_of_ints = Set(rand(-1000:1000, 2000))
    s2 = deepcopy(set_of_ints)
    
    for x in set_of_ints
        if x < 0
            pop!(set_of_ints, x)
            push!(set_of_ints, -x)
        end
    end
    @test set_of_ints == Set(map(abs, collect(s2)))
end
1 Like

Thanks, I suspected that this pattern working for me once was accidental. replace! seems to be the proper way to do that.

1 Like