Ruby 按键数组值获取嵌套哈希中的键值

Ruby 按键数组值获取嵌套哈希中的键值,ruby,Ruby,示例哈希: { "audio" => { "audio/aac" => ["aac"], "audio/mpeg" => ["mp3", "mp2"], "audio/mp4" => ["m4a", "m4b", "m4r", "3gp"], "audio/ogg" => ["ogg", "oga"], "audio/flac" => ["flac"], "audio/spe

示例哈希:

  {
    "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

正如您已经意识到的那样,以您想要的方式搜索现有的数据结构非常糟糕。假设您要反复搜索相同的数据,那么您应该为它创建一个索引

有很多方法可以做到这一点,但最简单的方法可能只是将散列展平并反转,以便键变成值,反之亦然。这样,您只需调用
content\u 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"
}

正如您已经意识到的那样,以您想要的方式搜索现有的数据结构非常糟糕。假设您要反复搜索相同的数据,那么您应该为它创建一个索引

有很多方法可以做到这一点,但最简单的方法可能只是将散列展平并反转,以便键变成值,反之亦然。这样,您只需调用
content\u 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"
}
试用

定义:

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

试用

定义:

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


解开这种结构最好在它被创建时完成。但是,您可以循环各种级别,并从中获得有用的信息。如果我将您的初始哈希分配给
mime\u 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"
}

解开这种结构最好在它被创建时完成。但是,您可以循环各种级别,并从中获得有用的信息。如果我将您的初始哈希分配给
mime\u 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"
}

恐怕这对这种杂凑不太起作用。如果键是一个数组,则会出现问题,因为
散列[“audio”].rassoc([“m4b”])
不会返回任何内容。你有没有举个例子?恐怕这在这种散列上并不像预期的那样有效。如果键是一个数组,则会出现问题,因为
散列[“audio”].rassoc([“m4b”])
不会返回任何内容。你有一个例子吗?是的,结构不理想,但它主要用于应用程序中的其他用途(因此是音频/视频组),而不是ext要求mime类型解析。是的,结构不理想,但它主要用于应用程序中的其他用途(因此是音频/视频组),ext.Nice不打算要求提供mime类型解析,也不知道
Array\35; product
.map+flatten(1)=flat\u map。散列[…]需要成对,无需进行完全展平。很好,不知道
Array\35; product
。map+flatten(1)=展平映射。散列[…]需要成对,无需进行完全展平。