“最红的”做事方式通常是使用对象。如果您不想创建一个成熟的类,您可以使用OpenStruct
.
require 'ostruct'
images = images.map { |image_hash| OpenStruct.new(image_hash) }
max_area = images.max_by(&:score).area
images.each do |image|
if image.area > 0
image.score += image.area / max_area
end
end
但是,如果您的代码开始变得过于复杂,并且您愿意引入库,我建议您使用Virtus:
require 'virtus'
class Image
include Virtus.model
attribute :area, Integer
attribute :id, Integer
attribute :score, Integer
# You probably have more context to name this better
def increment_score!(max_area)
if area > 0
self.score += area / max_area
end
end
end
class ImageCollection
include Virtus.model
attribute :images, Array[Image]
# Win all the Enumerable methods for free
include Enumerable
def each(&block)
images.each(&block)
end
def biggest_area
image_with_best_score.area
end
def image_with_best_score
images.max_by(&:score)
end
# You probably have more context to name this better
def increment_scores!
images.each { |image| image.increment_score!(biggest_area) }
end
end
images = ImageCollection.new(images: [{ area: 10, id: 39393, score: 10}, { area: 20, id: 33434, score: 5}])
images.increment_scores!
puts images.map(&:score).join(", ") # => 11, 7
当然,如果您只是将一个脚本放在一起,这是一个重大的过度杀伤,但如果您的逻辑开始变得过于混乱,到处都是数组和散列,那么它可能具有巨大的价值。