2011-10-17 15 views
9

Estoy buscando una buena manera de ordenar un hash en Perl primero por valor y luego por clave.Clasificar hash por valor y clave (en ese orden)

Ejemplo:

my %userids = (
    williams => "Marketing", 
    smith => "Research", 
    johnson => "Research", 
    jones => "Marketing", 
    brown => "Marketing", 
    davis => "Research" 
); 

Salida:

Marketing: brown 
Marketing: jones 
Marketing: williams 
Research: davis 
Research: johnson 
Research: smith 

Tenga en cuenta que el valor fue el primer nivel de clasificación. El segundo nivel de clasificación es clave. ¿Alguna idea de cómo hacer esto de una manera elegante y de alto rendimiento? ¡Gracias!

Respuesta

27

buena referencia: http://www.misc-perl-info.com/perl-sort.html#shv

#!/usr/bin/perl 

my %userids = (
    williams => "Marketing", 
    smith => "Research", 
    johnson => "Research", 
    jones => "Marketing", 
    brown => "Marketing", 
    davis => "Research" 
); 

foreach (sort { ($userids{$a} cmp $userids{$b}) || ($a cmp $b) } keys %userids) 
{ 
    print "$_: $userids{$_}\n"; 
} 
7

Me gustaría añadir una cosa más, utilizar \L sequence en la clasificación.

De Perlfaq4: ¿Cómo puedo ordenar un hash (opcionalmente por valor en lugar de clave)?

para hacer que nuestro fin informe de mayúsculas y minúsculas, utilizamos el \L sequence en una cadena entre comillas dobles para hacer todo en minúsculas. El bloque sort() luego compara los valores en minúscula para determinar en qué orden colocar las claves.

foreach (sort { $userids{$a} cmp $userids{$b} or "\L$a" cmp "\L$b") { 
    print "$_: $userids{$_}\n"; 
} 

Salida:

brown: Marketing 
jones: Marketing 
williams: Marketing 
davis: Research 
Johnson: Research # here 'J'ohnson, J is in uppercase(taking assumption), come as fifth record 
smith: Research 

2.

foreach (sort { $userids{$a} cmp $userids{$b} or $a cmp $b) { 
    print "$_: $userids{$_}\n"; 
} 

Salida:

brown: Marketing 
jones: Marketing 
williams: Marketing 
Johnson: Research # here it shifted to fourth record 
davis: Research 
smith: Research 
+0

diría que semánticamente que _sólo_ sentido al entrar en los elementos en la tabla hash . De lo contrario, obtendrás resultados inexplicables cuando el hash contenga tanto a Johnson como a Johnson. Es decir. al ordenar, difícilmente puede decir "las claves son equivalentes": según la definición tradicional, las tablas hash no pueden contener dos claves equivalentes – sehe

+0

sí, las claves verdaderas siempre serán únicas en hash, nunca contienen dos claves equivalentes, pero puede ver la diferencia en salida. –

+0

Puedo ver la diferencia en la salida. Es por eso que creo que sería una cosa extraña de hacer: viola el [principio de la menor sorpresa] (http://c2.com/cgi/wiki?PrincipleOfLeastAstonishment) en mi opinión – sehe

Cuestiones relacionadas