Question

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?

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top