How to Make Object Instance a Hash Key in Ruby

How to make object instance a hash key in Ruby?

See http://ruby-doc.org/core/classes/Hash.html

Hash uses key.eql? to test keys for
equality. If you need to use instances
of your own classes as keys in a Hash,
it is recommended that you define both
the eql? and hash methods. The hash
method must have the property that
a.eql?(b) implies a.hash == b.hash.

The eql? method is easy to implement: return true if all member variables are the same. For the hash method, use [@data1, @data2].hash as Marc-Andre suggests in the comments.

Best way to make object hash in Ruby?

Try using a Set instead of an array so the order doesn't matter. You have to have this line at the top:

require 'set'

Then make a Set containing both objects and use it to help implement the equality operator and hash method. I assume Set#hash behaves correctly and your can use it in your hash method. Set#== can be used to simplify your equality operator.

http://www.ruby-doc.org/stdlib-2.1.4/libdoc/set/rdoc/Set.html

Ruby instance variable and hash key - how it works

Ruby is one of many languages that distinguish "immediate values" and "reference values".

If I say x = 5; y = x; y = 6, then x is an immediate value, and still contains 5, not 6.

But if I say x = { value: 5 }, then x is a reference to a hash object. When I say y = x then y refers to the same hash object as x does. So y[:value] = 6 will make x[:value] == 6.

To prevent this behavior, look up "ruby deep copy", and use y = x.dup.

Make instance variable accessible through hash in Ruby

It's not "through Hash", it's "array access" operator.

To implement it, you need to define methods:

def [](*keys)
# Define here
end

def []=(*keys, value)
# Define here
end

Of course, if you won't be using multiple keys to access an element, you're fine with using just key instead of *keys, so that you have not an array of keys (even if only one is given), but just a single key.

Plenty of other classes implement it, namely Structs, so you're free to pick an existing implementation or roll out your own.

Getting instance variables to be affected by these methods means implementing them using instance_variable_get/instance_variable_set. Nothing fancy.

Ruby convert Object to Hash

class Gift
def initialize
@name = "book"
@price = 15.95
end
end

gift = Gift.new
hash = {}
gift.instance_variables.each {|var| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
p hash # => {"name"=>"book", "price"=>15.95}

Alternatively with each_with_object:

gift = Gift.new
hash = gift.instance_variables.each_with_object({}) { |var, hash| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
p hash # => {"name"=>"book", "price"=>15.95}

Ruby - Create a hash, where Keys are newly initialized Array objects

Do you need another array because you will modify or destroy the properties of the Circles in the first array? If so, and you can rely on the Cirlces' order in the array remaining the same, then just use the index value to correlate the values:

circle_area_hash = $s.reduce{|a, c| a[c.object_id] = c.area }

Also, consider that for your analyses, you may care more about the values, than the objects, per se. So then you could create

circle_area_hash = $s.reduce do |a, c| 
a[c.area] = (a[c.area].nil?) ? [c] : a[c.area] << c
end

This make the hash-keys bey the area value as, and the hash-values are each an array of the objects that have that area.

Then to get the key (largest area) you can:

circle_area_hash.max_by{|k,v| v.count}

Also, as a thought:

puts "How many Circles"
$s = (1...gets.to_i).each |j|
puts "Enter radius of Circle #{j}"
$s << Circle.new(gets.to_i)
end

$s[3].area

Create key in hash with inject method in Ruby

key = 'en.countries.new_one'

key.split(".").inject(y) do |h, k|
h.key?(k) ? h[k] : h[k] = "x value"
end


Related Topics



Leave a reply



Submit