2010-07-20 24 views
5

tengo un hash que tiene este aspecto:Inversión de un hash de valores múltiples en Perl

{ bmw  => { id => 1, color => brown } } 
{ mercedes => { id => 2, color => black } } 

Quiero revertir este hash en Perl para que apenas consigo un mapeo de id => name_of_car. ¿Debo usar la función inversa de alguna manera?

Nota: siempre puedo repetir el hash original y asignar las claves y los valores de acuerdo con el nuevo hash, tuerca que quería saber si había una manera más suave.

+0

Creo que deberías aceptar una de nuestras respuestas. ¿Cómo puedes ponerte más impermeable que el único delineador de Kinopiko? – masonk

Respuesta

6

no necesita un camino resbaladizo:

my %h = (
    bmw  => { id => 1, color => "brown" } , 
    mercedes => { id => 2, color => "black" } 
); 
my %j = map { ($h{$_}{id} => $_) } keys %h; 

for (keys %j) { 
    print "$_ $j{$_}\n"; 
} 

Salida:

 
$ ./silly.pl 
1 bmw 
2 mercedes 
+0

Oye, no es necesario que descuides tu solución. Tu manera se ve muy hábil para mí :). – masonk

+0

Sin embargo, esta es la forma habitual. –

+0

Veo que tenemos diferentes definiciones de "slick" – masonk

2

Lo que has enviado no es válida Perl, pero creo que tomo su significado. Una buena manera de hacerlo sería con un hash slice y un mapa.

my %hash = (
    bmw  => { id => 1, color => 'brown' }, 
    mercedes => { id => 2, color => 'black' }, 
); 
my %new_hash; 
@new_hash{ map { $_->{id} } values %hash } = keys %hash; 
+0

¿Por qué se usa un símbolo de alias (@) en la última línea antes de new_hash? – syker

+0

@syker: mire el enlace masonk proporcionado sobre "rebanada hash". –

+0

Esta es la sintaxis especial para una porción hash (vinculada anteriormente). Usted proporciona una lista de claves en el lado izquierdo y una lista de valores en el lado derecho. Perl garantiza que el orden en el que se devuelven los valores% hash es el mismo orden en el que se devuelven las claves% hash, por lo que esto funciona. – masonk

Cuestiones relacionadas