Reputation: 3
I am attempting to take JSON like this:
{"myhostname"=>
{"client"=>"exemplar", "tag"=>"mytag"},
"mysecondhost"=>
{"client"=>"exemplar", "tag"=>"mytag2"},
"myhost2"=>
{"client"=>"exemplar", "envtag"=>"mytag2"}}
My goal is to output something like:
mytag:myhostname
mytag2:mysecondhost, myhost2
It'll need to be JSON at the end of the day, but I'm using pyjojo and that seems to do a good job of reformatting it. I'm trying to get a list of hosts for each key.
The hostnames are dynamic. It's been easy to get an output of "tag:host" for each of these, but I'm having a hard time dealing with the situation where the tag is duplicated, and I need to return each host as a comma separated value.
Thank you in advance.
Upvotes: 0
Views: 892
Reputation: 118261
To remap key value pairs in a JSON object I think you want something like this:
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"]}
Then iterate through the hash as below:
new_hash.each { |k,v| puts "k: #{v.join(',')}" }
# >> k: myhostname
# >> k: mysecondhost,myhost2
Explanation:
Look at this #map
method.
# collecting hostname and tag key value as an array
hash.map { |k,h| [k,h.values.last] }
# => [["myhostname", "mytag"],
# ["mysecondhost", "mytag2"],
# ["myhost2", "mytag2"]]
Look at this #group_by
method.
# 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"]]]
Look at this Hash::[]
method.
# finally got the desired Hash
Hash[grouped_hash.map { |k,v| [k,v.map(&:first)] }]
# => {"mytag"=>["myhostname"], "mytag2"=>["mysecondhost", "myhost2"]}
Upvotes: 4