在ruby中组合重复的哈希键

时间:2014-03-19 21:34:27

标签: ruby json hash

我试图像这样采用JSON:

{"myhostname"=>
  {"client"=>"exemplar", "tag"=>"mytag"},
 "mysecondhost"=>
  {"client"=>"exemplar", "tag"=>"mytag2"},
 "myhost2"=>
  {"client"=>"exemplar", "envtag"=>"mytag2"}}

我的目标是输出如下内容:

mytag:MYHOSTNAME
mytag2:mysecondhost,myhost2

它应该在一天结束时成为JSON,但我使用pyjojo,这似乎很好地重新格式化它。我试图获取每个密钥的主机列表。

主机名是动态的。很容易得到"标签的输出:host"对于其中的每一个,但我很难处理标记重复的情况,我需要将每个主机作为逗号分隔值返回。

提前谢谢。

1 个答案:

答案 0 :(得分:4)

要重新映射JSON对象中的键值对,我想你想要这样的东西:

hash = { 
         "myhostname"=> {"client"=>"exemplar", "tag"=>"mytag"},
         "mysecondhost"=> {"client"=>"exemplar", "tag"=>"mytag2"},
         "myhost2"=>{"client"=>"exemplar", "envtag"=>"mytag2"}
       }

new_hash = Hash[ 
                 hash.map { |k,h| [k,h.values.last] }.group_by(&:last)
                 .map { |k,v| [k,v.map(&:first)] }
               ]
# => {"mytag"=>["myhostname"], "mytag2"=>["mysecondhost", "myhost2"]}

然后迭代哈希,如下所示:

 new_hash.each { |k,v| puts "k: #{v.join(',')}" }
# >> k: myhostname
# >> k: mysecondhost,myhost2

说明:

请看这个#map方法。

# collecting hostname and tag key value as an array
hash.map { |k,h| [k,h.values.last] }
# => [["myhostname", "mytag"],
#     ["mysecondhost", "mytag2"],
#     ["myhost2", "mytag2"]]

请看这个#group_by方法。

# grouping on the tag key's value as to get a below hash
grouped_hash = hash.map { |k,h| [k,h.values.last] }.group_by(&:last)
# => {"mytag"=>[["myhostname", "mytag"]],
#     "mytag2"=>[["mysecondhost", "mytag2"], ["myhost2", "mytag2"]]}

# from the gropued has based on tag key's value, I would collect the tag name and 
# host names associated with the specific tag.
grouped_hash.map { |k,v| [k,v.map(&:first)] }
# => # => [["mytag", ["myhostname"]], ["mytag2", ["mysecondhost", "myhost2"]]]

请看这个Hash::[]方法。

# finally got the desired Hash
Hash[grouped_hash.map { |k,v| [k,v.map(&:first)] }]
# => {"mytag"=>["myhostname"], "mytag2"=>["mysecondhost", "myhost2"]}