/ / Ottenere il valore chiave nell'hash nidificato in base ai valori dell'array chiave - ruby

Ottenere il valore chiave nell'Hash annidato per valori di matrice chiave - ruby

Hash di esempio:

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

Qual è il modo migliore data un'estensione di file per ottenere il tipo di contenuto associato (la prima corrispondenza va bene)?

La ricerca di "flac" dovrebbe restituire "audio / flac".

Attualmente sto usando questo:

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

risposte:

4 per risposta № 1

Svelare quel tipo di struttura è meglio farlo quando viene creato. Ma puoi passare attraverso i vari livelli e ottenere qualcosa di utile da esso. Se assegnassi il tuo hash iniziale a mime_hash Posso svelarlo usando:

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

o più verbalmente:

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

Che ritornerà:

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

0 per risposta № 2

Come hai già realizzato la struttura dei datiè orribile cercare nel modo desiderato. Supponendo che stai cercando gli stessi dati più e più volte su ciò che dovresti fare è creare un indice per esso.

Esistono molti modi per farlo, ma il più semplice è probabilmente quello di appiattire l'hash e invertirlo in modo che le tue chiavi diventino valori e viceversa. In questo modo puoi semplicemente cercarlo chiamando content_types["flac"]

Una sezione dell'hash di esempio potrebbe finire così:

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

0 per risposta № 3

Prova a usare rassoc ()

Definizione:

Cerca attraverso l'hash confrontando obj con il valore usando ==. Restituisce la prima coppia chiave-valore (matrice a due elementi) che corrisponde. Vedi anche Array # rassoc.

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