In ruby, why is Set unordered while Hash is guaranteed in insertion order?
In ruby, why is Set unordered while Hash is guaranteed in insertion order?
Hash in ruby 2.5.1:
Hashes enumerate their values in the order that the corresponding keys were inserted.
Set in ruby 2.5.1:
Set implements a collection of unordered values with no duplicates.
I thought set was implemented as a Hash in ruby. Then why is Set unordered while Hash is guaranteed in insertion order?
UPDATE:
I understand that mathematically sets are supposed to be unordered.
An important question arises, even though the Set
class is actually in insertion order, it is not documented. I think the documentation should be updated.
Set
Even in the Set#add
source, we can see it's actually using Hash
:
Set#add
Hash
# File set.rb, line 348
def add(o)
@hash[o] = true
self
end
Note: I don't mean to spark off discussion, but think it's important that this fact is documented somewhere. If not in the official docs, atleast on stack overflow.
1 Answer
1
Set is semantically unordered; a compliant implementation could build it atop an actually-unordered core. (I'm not sure what JRuby does, for example, though I imagine they probably use the same Hash-based implementation as CRuby.)
As you note, Set is in practice implemented using Hash -- which means it will in fact preserve insertion order... it's just not guaranteed by the specification.
If you're asking why it's defined that way, it's very possible that documentation predates guaranteed Hash ordering and has never been revised (and equally possible that it's a conscious choice). It was recently raised in https://bugs.ruby-lang.org/issues/14069, but has seen no discussion so far.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
The fact that sets are implemented with hashes is irrelevant. At issue is merely whether sets should preserve insertion order. One of the pro arguments is that it could be done efficiently, since sets employ hashes under the covers, but that is not the central issue. As to "why" sets don't preserve insertion order you will have to ask the Ruby monks. Evidently, they haven't been persuaded that such a change would be desirable. As the question calls for opinions, it's not really suitable for SO. (Click on point 2 under "Asking" at SO help.)
– Cary Swoveland
Jul 1 at 18:21