I need to iterate over a Set whose elements will be deleted in the process.However, some deleted elements are included in the iteration, e.g. the element 4 in the code below.
Problem 1. could be fixed by having next() check the next value before returning it, which would allow removing elements from the Set. Any change would likely make iteration over sets slightly less efficient. Do we want to support this?
Adding elements to the Set will never be a good idea.
true; but in python you get an exception. julia is silently trashing the data...
(Most of this is actually defined in Dict, upon which Set is defined, but the essentials are correct and easier to understand above, IMHO.)As with all iteration in Julia, for iteration over a Set, start, next, and done functions are defined (see http://docs.julialang.org/en/latest/stdlib/base/#iteration).So, no one has really explained why this is happening.Sets are built on top of hash tables. The hash table itself is just an array, many entries of which are not being used.
start(s::Set) iterates over the hash table and returns the index of the first used entry (no values are returned yet from the Set).
next(s::Set, i) returns (s.hash_table[i], i_next), where s.hash_table[i] is the value for the current iteration, and i_next is the location of the following entry in the hash table.
done(s::Set, i) returns true if we're done iterating (which will specifically be true when i > length(s.hash_table))
The problem with modifying the table is two-fold:
- next(s::Set, i) has already returned the location of the next entry in the hash table; if you delete that entry, the next location is actually invalid
- adding values to the hash table may trigger a resize (removing does not)
Problem 1. could be fixed by having next() check the next value before returning it, which would allow removing elements from the Set. Any change would likely make iteration over sets slightly less efficient. Do we want to support this?
Adding elements to the Set will never be a good idea.
For now, I'll take back my recommendation about PersistentSets in the FunctionalCollections.jl package, as they seem to have other issues, and I'm not sure now if they'll actually work.
oh, i'm sorry. no, i;m wrong. i missed the "-1". ive completely misunderstood the thread. :o(
To realize what you want to do, you can add the elements to be removed to another set.On each iteration, verify that the current element isn't already in the set of elements to be removed, and after the loop, clean the first set using the elements of the second one.