在数组的哈希需要计数的同时,在ruby中创建其他键对相同的时间

2022-01-30 14:49:35 标签 rubyhash

我需要帮助计数出现在哈希数组“aoh”和产生和预期的输出“总结”。

这是原始数据“aoh”:

aoh = [{:interface=>"1A",
        :host=>"host_1",
        :status=>"online"},
       {:interface=>"1A",
        :host=>"host_2",
        :status=>"online"},
       {:interface=>"1A",
        :host=>"host_3",
        :status=>"offline"},
       {:interface=>"2A",
        :host=>"host_4",
        :status=>"offline"},
       {:interface=>"2A",
        :host=>"host_5",
        :status=>"offline"},
       {:interface=>"2A",
        :host=>"host_6",
        :status=>"online"}
      ]

这是预期输出

summary = [{:interface=>"1A", :online_hosts=> 2, :offline_hosts=> 1},
           {:interface=>"2A", :online_hosts=> 1, :offline_hosts=> 2}]

注意:我正在尝试这个代码…

    summary = Hash.new { |h, k| h[k] = { online: 0, offline: 0 } }
      aoh.each do |item|
        summary[item[:interface]][item[:status] == 'online' ? :online : :offline] += 1
      end
    summary
=> {"1A"=>{:online=>2, :offline=>1}, "2A"=>{:online=>1, :offline=>2}} # almost, but it is not the expected result

这几乎产生了预期的结果,但这种方式的接口值被移到哈希之外作为一个键,哈希键名不是预期的。我确实需要在哈希中保留接口密匙对。

###如果你尝试直接创建一个哈希数组,你必须在每次迭代中扫描数组来找到接口的摘要。这既尴尬又昂贵。

构建哈希的哈希更容易、更快。做您正在做的同样的事情,但也将接口名称存储在摘要中。然后取结果散列的值。

# Same thing, but also store the interface name in the value.
summary = Hash.new do |h, k| 
  h[k] = { interface: k, online: 0, offline: 0 }
end
# Same thing, just easier to read.
aoh.each do |item|
  status = item[:status] == 'online' ? :online : :offline
  summary[item[:interface]][status] += 1
end
# What you want is the values of the hash.
p summary.values

###你可以使用Enumerable#group_by。

aoh.group_by { |h| h[:interface] }
   .map do |k,a|
      n = a.count { |h| h[:status] == "online" }
      { interface: k, online_hosts: n, offline_hosts: a.size - n }
    end
  #=> [{:interface=>"1A", :online_hosts=>2, :offline_hosts=>1},
  #    {:interface=>"2A", :online_hosts=>1, :offline_hosts=>2}]

注意:

aoh.group_by { |h| h[:interface] }
  #=> {"1A"=>[{:interface=>"1A", :host=>"host_1", :status=>"online"},
  #           {:interface=>"1A", :host=>"host_2", :status=>"online"},
  #           {:interface=>"1A", :host=>"host_3", :status=>"offline"}],
  #    "2A"=>[{:interface=>"2A", :host=>"host_4", :status=>"offline"},
  #           {:interface=>"2A", :host=>"host_5", :status=>"offline"},
  #           {:interface=>"2A", :host=>"host_6", :status=>"online"}]}

另一种方法是使用Hash#update(又名merge!)的形式,它使用一个块来确定出现在被合并的两个哈希表中的键值。这里的block是do |_on|…结束。关于三个块变量_ o和n的定义,请参阅文档。我使用了一个下划线来表示那个变量,以向读者发出信号,表明它在块计算中没有被使用,这是一种常见的约定。)

aoh.each_with_object({}) do |g,h|
  h.update(
    g[:interface]=>
      { interface: g[:interface],
        online_hosts: g[:status] == "online" ? 1 : 0,
        offline_hosts: g[:status] == "online" ? 0 : 1
      }
  ) do |_,o,n|
      { interface: o[:interface],
        online_hosts: o[:online_hosts]+n[:online_hosts],
        offline_hosts: o[:offline_hosts]+n[:offline_hosts]
      }
    end
end.values
  #=> [{:interface=>"1A", :online_hosts=>2, :offline_hosts=>1},
  #    {:interface=>"2A", :online_hosts=>1, :offline_hosts=>2}]

注意哈希值的接收方是:

{"1A"=>{:interface=>"1A", :online_hosts=>2, :offline_hosts=>1},
 "2A"=>{:interface=>"2A", :online_hosts=>1, :offline_hosts=>2}}
阅读全文

▼ 版权说明

相关文章也很精彩
推荐内容
更多标签
相关热门
全站排行
随便看看

错说 cuoshuo.com —— 程序员的报错记录

部分内容根据CC版权协议转载;网站内容仅供参考,生产环境使用务必查阅官方文档

辽ICP备19011660号-5

×

扫码关注公众号:职场神器
发送: 1
获取永久解锁本站全部文章的验证码