Вопрос

I have an array of hashes, called images that look like this:

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

I want to increment the score of each object in percentage to the max area. So, here is how I do it right now:

 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

Is there any other Ruby way of doing this?

Это было полезно?

Решение

The "rubyiest" way of doing things is usually by using objects. If you don't want to create a full-fledged class, you can get started by using 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

However, if your code starts to get too complex, and you are willing to bring in a library, I would recommend using 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

Of course, this is a major overkill if you are just throwing together a script, but it can be of immense value if your logic start to get too messy with arrays and hashes everywhere.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top