繁体   English   中英

Hash/Ruby - 在哈希中选择最后 4 个值(平均)

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

我有一个哈希,我选择仪表板的所有数据来显示性能,因为显示最新值并不总是有帮助,我试图从哈希中选择最后 4 个值。

我尝试了thing.last(4) ,但无济于事。

代码如下,本质上是试图显示top_points的最后 4 个或平均点。

注意:红宝石 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

下面使用Hash#select来避免需要将哈希转换为数组、操作数组然后将其转换回哈希。

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} 

或者,如果使用 Ruby 2.5+,可以使用Hash#slice

h.slice(*h.keys[2..-1])
  #=> {"f"=>3, "e"=>1, "c"=>3, "a"=>7}

如果使用 Ruby 2.6+,可以使用Endless range

h.slice(*h.keys[2..])
  #=> {"f"=>3, "e"=>1, "c"=>3, "a"=>7}
metrics.sort.last(4).to_h

将为您提供最后四个元素的哈希值。


假设您最初不想排序,请使用相同的想法:

metrics.to_a.last(4).to_h

更新:鉴于您添加了 1.9 限制并且Array#to_h从 2.1 开始,您可以将x.to_h替换为Hash[x]

或者,如果您不需要哈希并且想要遍历键/值对,请省略.to_h部分并继续.each do |key, value| 几乎会做同样的事情。

为了获取散列的最后四个元素,您应该首先将其map为一个数组,获取所需的索引,然后再次将数组转换为散列。

例如:

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} 

在您的特定情况下,代码可能如下所示:

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

另一种写法可能是:

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'] }}

更新:与 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'] }}

您可以将散列转换为 2 元素数组,选择最后一个元素并转换回散列:

top_points = {}
(1..10).each { |i| top_points[i] = i*2 }
# => top_points == {1=>2, 2=>4, 3=>6, 4=>8, 5=>10, 6=>12, 7=>14, 8=>16, 9=>18, 10=>20}

Hash[top_points.to_a[-4..-1]]
# => {7=>14, 8=>16, 9=>18, 10=>20}

你需要使用 ruby​​ 1.9+ 才能工作(因为这个版本它按给定的顺序保存哈希键)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM