通过键数组值获取嵌套Hash中的键值

时间:2012-04-30 05:24:31

标签: ruby

示例哈希:

  {
    "audio" =>  {
      "audio/aac" => ["aac"],
      "audio/mpeg" => ["mp3", "mp2"],
      "audio/mp4" => ["m4a", "m4b", "m4r", "3gp"],
      "audio/ogg" => ["ogg", "oga"],
      "audio/flac" => ["flac"],
      "audio/speex" => ["spx"],
      "audio/x-ms-wma" => ["wma"],
      "audio/x-pn-realaudio" => ["rm", "ram"],
      "audio/vnd.wave" => ["wav"],
      "audio/x-musepack" => ["mpc", "mp+", "mpp"],
      "audio/x-aiff" => ["aiff", "aif", "aifc"],
      "audio/x-tta" => ["tta"]
    },
    "video" =>  {
      "video/mp4" => ["mp4"],
      "video/mpeg" => ["mpg", "mpeg"],
      "video/x-m4v" => ["m4v"],
      "video/quicktime" => ["mov"],
      "video/x-msvideo" => ["avi"],
      "video/x-flv" => ["flv"],
      "video/webm" => ["webm"]
    }
  }

获取相关内容类型的文件扩展名的最佳方法是什么(第一次匹配是否合适)?

搜索“flac”应该返回“audio / flac”。

目前我正在使用它:

hsh.each_key do |group|
  hsh[group].each do |k,v|
    return k if v.include?(extension)
  end
end

3 个答案:

答案 0 :(得分:4)

解开那种结构最好在创建时完成。但是,您可以遍历各个级别并从中获得有用的东西。如果我将初始哈希值分配给mime_hash,我可以使用以下方法解析它:

Hash[*mime_hash.map{ |av, types| types.map{ |mime_type, extensions| extensions.product([mime_type]) } }.flatten] 

或更详细地说:

Hash[
  *mime_hash.map{ |av, types| 
    types.map{ |mime_type, extensions| 
      extensions.product([mime_type]) 
    } 
  }.flatten
] 

将返回:

{
     "aac" => "audio/aac",
     "mp3" => "audio/mpeg",
     "mp2" => "audio/mpeg",
     "m4a" => "audio/mp4",
     "m4b" => "audio/mp4",
     "m4r" => "audio/mp4",
     "3gp" => "audio/mp4",
     "ogg" => "audio/ogg",
     "oga" => "audio/ogg",
    "flac" => "audio/flac",
     "spx" => "audio/speex",
     "wma" => "audio/x-ms-wma",
      "rm" => "audio/x-pn-realaudio",
     "ram" => "audio/x-pn-realaudio",
     "wav" => "audio/vnd.wave",
     "mpc" => "audio/x-musepack",
     "mp+" => "audio/x-musepack",
     "mpp" => "audio/x-musepack",
    "aiff" => "audio/x-aiff",
     "aif" => "audio/x-aiff",
    "aifc" => "audio/x-aiff",
     "tta" => "audio/x-tta",
     "mp4" => "video/mp4",
     "mpg" => "video/mpeg",
    "mpeg" => "video/mpeg",
     "m4v" => "video/x-m4v",
     "mov" => "video/quicktime",
     "avi" => "video/x-msvideo",
     "flv" => "video/x-flv",
    "webm" => "video/webm"
}

答案 1 :(得分:0)

正如您已经意识到的那样,您所拥有的数据结构很难以您想要的方式进行搜索。假设你要一遍又一遍地搜索相同的数据,那么就为它创建一个索引。

有很多方法可以做到这一点,但最简单的方法可能就是将哈希变平并反转它,以便你的键成为值,反之亦然。这样您就可以通过调用content_types['flac']

来搜索它

示例哈希的一部分可能会像这样结束:

{
  "aac" => "audio/aac",
  "mp3" => "audio/mpeg",
  "mp2" => "audio/mpeg",
  "m4a" => "audio/mp4",
  "m4b" => "audio/mp4",
  "m4r" => "audio/mp4",
  "3gp" => "audio/mp4",
  "flac" => "audio/flac"
}

答案 2 :(得分:0)

尝试使用rassoc()

定义:

通过使用==将obj与值进行比较的哈希进行搜索。返回匹配的第一个键值对(双元素数组)。另请参见Array#rassoc。

a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
a.rassoc("two")    #=> [2, "two"]
a.rassoc("four")   #=> nil