1

我有一个哈希数组,称为images如下所示:

[{ area: 10, id: 39393, score: 10}, { area: 20, id: 33434, score: 5}, ...]

我想将每个对象的分数以百分比增加到最大区域。所以,这就是我现在的做法:

 max_area = images.max_by { |el| el["score"] }["area"]
    images.each do |image|
      if image["area"] > 0
        image["score"] += image["area"] / max_area
      end
    end

还有其他 Ruby 方法可以做到这一点吗?

4

1 回答 1

1

“最红的”做事方式通常是使用对象。如果您不想创建一个成熟的类,您可以使用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

当然,如果您只是将一个脚本放在一起,这是一个重大的过度杀伤,但如果您的逻辑开始变得过于混乱,到处都是数组和散列,那么它可能具有巨大的价值。

于 2013-11-06T18:29:45.567 回答