如何在哈希中汇总哈希?

Uzz*_*zar 5 ruby hashmap

我有这样的哈希:

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",}
Run Code Online (Sandbox Code Playgroud)

我想单独确定五大洲以及属于它们的国家,这样我最终会得到这样的结论:

{"Africa" => ["Senegal", "Somalia"]}
{"Europe" => ["Albania", "Andorra", "Austria"]}
Run Code Online (Sandbox Code Playgroud)

适用于所有大陆.

我试过这个:

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
Run Code Online (Sandbox Code Playgroud)

而且效果太好了.我得到一个新的哈希:

{Africa => []} 
Run Code Online (Sandbox Code Playgroud)

但我有两个问题:

  1. 我为每个非洲国家创建了一个新哈希.
  2. 每个新哈希都包含所有密钥,其中包括所有非非洲国家/地区.

我认为第一个问题与each方法有关所以我必须设置一些条件,对吧?

第二个问题,我不知道如何解决.

任何指针都会更受欢迎.

Mau*_*res 3

SomeHash首先也是最重要的一点是,不要像使用和那样在 Ruby 中使用大写字母表示变量XPath。当变量名以大写字母开头时,意味着它是一个常量,而您可能不希望它成为常量。

each不是最好的方法,您可以更简单地执行此操作,inject如下所示:

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
Run Code Online (Sandbox Code Playgroud)

其输出是:

{"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"]}
Run Code Online (Sandbox Code Playgroud)

您拥有按大陆分组的所有国家/地区,您可以选择其中任何一个。

在您的代码中应该这样放置:

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
Run Code Online (Sandbox Code Playgroud)