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
The following uses Hash#select to avoid the need to convert the hash to an array, manipulate the array and then convert it back to a hash.
h = { "b"=>1, "d"=>6, "f"=>3, "e"=>1, "c"=>3, "a"=>7 }
sz = h.size
#=> 6
h.select { (sz -= 1) < 4 }
#=> {"f"=>3, "e"=>1, "c"=>3, "a"=>7}
Alternatively, if using Ruby 2.5+ one could use Hash#slice:
h.slice(*h.keys[-4..-1])
#=> {"f"=>3, "e"=>1, "c"=>3, "a"=>7}
and if using Ruby 2.6+ one could employ an Endless range:
h.slice(*h.keys[-4..])
#=> {"f"=>3, "e"=>1, "c"=>3, "a"=>7}
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'] }}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With