开发者

selecting hash values by value property in ruby

开发者 https://www.devze.com 2023-01-17 04:36 出处:网络
In Ruby, I have a hash of objects. Each object has a type and a value. I am trying to design an efficient function that can get the average of the values of all of objects of a certain type within the

In Ruby, I have a hash of objects. Each object has a type and a value. I am trying to design an efficient function that can get the average of the values of all of objects of a certain type within the hash.

Here is an example of how this is currently implemented:

#the hash is composed of a number of objects of class Robot (example name)
class Robot
  attr_accessor :type, :value

  def initialize(type, value)
    @type = type
  开发者_如何学Python  @value = value
  end

end


#this is the hash that inclues the Robot objects
hsh = { 56 => Robot.new(:x, 5), 21 => Robot.new(:x, 25), 45 => Robot.new(:x, 35), 31 => Robot.new(:y, 15), 0 => Robot.new(:y, 5) }


#this is the part where I find the average
total = 0
count = 0
hsh.each_value { |r|  
if r.type == :x        #is there a better way to get only objects of type :x ?
  total += r.value 
  count += 1
end
} 

average = total / count

So my question is:

is there a better way to do this that does not involve looping through the entire hash?

Note that I can't use the key values because there will be multiple objects with the same type in the same hash (and the key values are being used to signify something else already).

If there is an easy way to do this with arrays, that would also work (since I can convert the hash to an array easily).

Thanks!

EDIT: fixed error in my code.


hsh.values.select {|v| v.type == :x}.map(&:value).reduce(:+) / hsh.size

I am trying to design an efficient function that can get the average of the values of all of objects of a certain type within the hash

Unless I misunderstood what you are trying to say, this is not what the code you posted does. The average value of the :x robots is 21 (there's 3 :x robots, with values 5, 25 and 35; 5 + 25 + 35 == 65 and 65 divided by 3 robots is 21), but your code (and mine, since I modeled mine after yours) prints 13.

is there a better way to get only objects of type :x ?

Yes. To select elements, use the select method.

is there a better way to do this that does not involve looping through the entire hash?

No. If you want to find all objects with a given property, you have to look at all objects to see whether or not they have that property.

Do you have actual hard statistical evidence that this method is causing your performance bottlenecks?


You can also directly map the keys like this

hsh.values.map {|k| k[:x]}.reduce(:+) / hsh.size
0

精彩评论

暂无评论...
验证码 换一张
取 消