I have a hash like this:
Some_hash =
{"Albania"=>"Europe",
"Andorra"=>"Europe",
"Austria"=>"Europe",
Lebanon"=>"Asia",
"Macau"=>"Asia",
"Malaysia"=>"Asia",
"Papua New Guinea"=>"Asia",
"Jamaica"=>"North America",
"Martinique"=>"North America",
"Argentina"=>"South America",
"Chile"=>"South America",
"Sao Tome and Principe"=>"Africa",
"Senegal"=>"Africa",
"Somalia"=>"Africa",}
I would like to identify the five continents individually, and the countries that belong to them, such that I end up with something like this:
{"Africa" => ["Senegal", "Somalia"]}
{"Europe" => ["Albania", "Andorra", "Austria"]}
for all of the continents.
I tried this:
def country
inflation_hash = {}
XPath.match( data, "//country").map do |element|
inflation_hash[element.attributes["name"]] = element.attributes["continent"]
end
inflation_hash.each do |country, continent|
new_hash = {}
if inflation_hash.has_value?("Africa") == true
new_hash["Africa"] = inflation_hash.keys
puts new_hash
end
end
end
and it works much too well. I get a new hash:
{Africa => []}
but I have two problems:
I think the first problem has to do with the each
method so I have to set some conditional, right?
The second problem, I have no idea how to fix.
Any pointers would be greater appreciated.
First and foremost don't use upper-case letters for variables in Ruby as you did with SomeHash
and XPath
. When a variable name starts with an upper-case letter, it means it's a constant and you probably didn't want it to be a constant.
each
is not the best way to do this, you can do this much more simply with inject
as in:
countries = {
"Albania"=>"Europe",
"Andorra"=>"Europe",
"Austria"=>"Europe",
"Lebanon"=>"Asia",
"Macau"=>"Asia",
"Malaysia"=>"Asia",
"Papua New Guinea"=>"Asia",
"Jamaica"=>"North America",
"Martinique"=>"North America",
"Argentina"=>"South America",
"Chile"=>"South America",
"Sao Tome and Principe"=>"Africa",
"Senegal"=>"Africa",
"Somalia"=>"Africa"}
by_continents = countries.inject({}) do |memo, (k,v)|
memo[v] ||= []
memo[v] << k
memo
end
The output for this is:
{"Europe"=>["Albania", "Andorra", "Austria"], "Asia"=>["Lebanon", "Macau", "Malaysia", "Papua New Guinea"], "North America"=>["Jamaica", "Martinique"], "South America"=>["Argentina", "Chile"], "Africa"=>["Sao Tome and Principe", "Senegal", "Somalia"]}
You have all countries grouped by continent and you can pick any one of them.
In your code it should be placed like this:
def country
inflation_hash = {}
XPath.match( data, "//country").map do |element|
inflation_hash[element.attributes["name"]] = element.attributes["continent"]
end
by_continents = inflation_hash.inject({}) do |memo, (k,v)|
memo[v] ||= []
memo[v] << k
memo
end
puts by_continents.inspect
by_continents
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With