Spartacus38 Spartacus38 - 7 months ago 28
Ruby Question

Hash/Ruby - Select last 4 values (to average) in hash

I have a hash, that I select all the data for a dashboard to display performance, since displaying the latest value isn't always helpful, I'm trying to select the last 4 values from a hash.

I have attempted the

thing.last(4)
, but to no avail.

Code is below, essentially trying to display the last 4 from
top_points
, or average points.

Note: Ruby 1.9

metric.sort.each do |key, value|
top_point = { x: Time.parse(key).to_time.to_i, y: value['top_10'] }
top_points << top_point

average_point = { x: Time.parse(key).to_time.to_i, y: value['average'] }
average_points << average_point
end

Answer

in order to get the last four elements of your hash, you should first map it as an array, get the indexes desired and then transform again the array into an hash.

For example:

2.2.1 :001 > hash = {a: 1, b: 2, c: 3, d: 4, e: 5}
 => {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5} 
2.2.1 :002 > hash.map{|h| h}[-4..-1].to_h
 => {:b=>2, :c=>3, :d=>4, :e=>5} 

In your specific case, the code might look like this:

metric.sort.map{|h| h}[-4..-1].to_h.each do |key, value|
    top_point = { x: Time.parse(key).to_time.to_i, y: value['top_10'] }
    top_points << top_point

    average_point = { x: Time.parse(key).to_time.to_i, y: value['average'] }
    average_points << average_point
  end

Another way to write it could be:

last_four_metrics = metric.sort.map{|h| h}[-4..-1].to_h
top_points = last_four_metrics.map{|k, v| { x: Time.parse(k).to_time.to_i, y: v['top_10'] }}
average_points = last_four_metrics.map{|k, v| { x: Time.parse(k).to_time.to_i, y: v['average'] }}

Update: compatibility with Ruby 1.9

last_four_metrics = Hash[ metric.sort.map{|h| h}[-4..-1] ]

top_points = last_four_metrics.map{|k, v| { x: Time.parse(k).to_time.to_i, y: v['top_10'] }}
average_points = last_four_metrics.map{|k, v| { x: Time.parse(k).to_time.to_i, y: v['average'] }}