I have a method that selects all the rows from my table like this:
smtp_status_raw = my_table.select(:message, :is_valid, :hostname).map { |h| h.values }
This returns an array that's like this:
[{:message=>"blah", :is_valid=>true, :hostname=>"1"}, {:message=>"blah", :is_valid=>true, :hostname=>"2"}, {:message=>"blah", :is_valid=>true, :hostname=>"3}]
Using the above information, I want to create a hash that looks like this:
{
:node_status =>
{
{:hostname => "1", :message: "blah"},
{:hostname => "2", :message: "blah"},
{:hostname => "3", :message: "blah"}
}
}
First of all, my question - is it possible to create a hash like the above? In the above example Sequel query, I have three objects which are three separate hosts, and I want to add those three hosts into a :node_status
key. Is that possible? If that's not a valid hash, what is an alternative?
Second, this is what I've tried:
# Initialize the hash
smtp_status_hash = { :node_status: => nil }
I've initialized the smtp_status_hash
hash with a node_status
key in it, but I am not sure how to nest the query results..
That's not a valid hash, because you have 3 values, but no keys in the :node_status
subhash. You could do something like:
smtp_status_raw = [
{:message=>"blah", :is_valid=>true, :hostname=>"1"},
{:message=>"blah", :is_valid=>true, :hostname=>"2"},
{:message=>"blah", :is_valid=>true, :hostname=>"3"}
]
{
node_status: smtp_status_raw.collect do |hash|
hash.reject { |key, value| key == :is_valid }
end
}
to get the values in :node_status
as an array:
{
:node_status=>[
{:message=>"blah", :hostname=>"1"},
{:message=>"blah", :hostname=>"2"},
{:message=>"blah", :hostname=>"3"}
]
}
Or you could do something like:
{
node_status: smtp_status_raw.collect do |hash|
[hash[:hostname], hash[:message]]
end.to_h
}
which sets up a sub hash with the key
being the :hostname
and value
being :message
:
{
:node_status=>{
"1"=>"blah",
"2"=>"blah",
"3"=>"blah"
}
}
or if you had more keys you wanted to keep:
{
node_status: smtp_status_raw.collect do |hash|
[hash[:hostname], hash.reject { |key, value| key == :is_valid }]
end.to_h
}
which is still a hash where the key
is the :hostname
but the value
has another hash:
{
:node_status=>{
"1"=>{:message=>"blah", :hostname=>"1"},
"2"=>{:message=>"blah", :hostname=>"2"},
"3"=>{:message=>"blah", :hostname=>"3"}
}
}
To set the values of a key after the Hash
has been created you can do something like:
smtp_status_hash = { node_status: nil }
smtp_status_hash[:node_status] = "Whatever you want here"
You can read more about Hash
and its methods, and how you can select
and reject
to keep or remove keys from a hash. Hashes, though are a dictionary structure and must always have a key
and a single value
, though that value may be an Array
or another Hash
.