Is there a hash mechanism in Ruby where you can quickly test for membership but not necessarily be able to enumerate the members?
For example, I want to do something like:
members = MembershipHash.new
members << 10
members << 28
members.include? 10
# returns true
members.include? 88
# returns false
I'd like it to be a string representation, so if I have 1M entries, i don't need the overhead of storing 1M entries, like an array. Kind of like Digest::SHA256.hexdigest, but where you could query it to see if a particular value is in it.
Is there anything like this in ruby?
Thanks for any help, kevin
CodePudding user response:
I believe ruby sets fit the case
irb(main):008:0> require 'set'
=> false
irb(main):009:0> members = Set.new
=> #<Set: {}>
irb(main):010:0> members << 10
irb(main):011:0> members << 28
=> #<Set: {10, 28}>
irb(main):012:0> members.include? 10
=> true
CodePudding user response:
I don't need the overhead of storing 1M entries
It's impossible to "test for membership" without storing the members. (How would the test work??)
You may be able to save memory by using e.g. Digest::SHA256.hexdigest
, as you suggest, but this only makes sense if the members are very large (e.g. image files), not small (e.g. the two examples you actually gave, of the numbers 10
and 28
):
Digest::SHA256.hexdigest('28')
=> "59e19706d51d39f66711c2653cd7eb1291c94d9b55eb14bda74ce4dc636d015a"
There is no built-in ruby library to automatically do this for you, but it's a fairly straightforward to do manually, e.g.
require 'set'
member_shas = Set.new
member_shas << Digest::SHA256.hexdigest(big_data_1)
member_shas << Digest::SHA256.hexdigest(big_data_2)
# ...
members.include? Digest::SHA256.hexdigest(thing_to_check)
...Or you could create your own class to do this Digest::SHA256.hexdigest
conversion automatically, by defining your own <<
and include?
methods.
You could also consider using a database, instead.