2012-06-05 13 views

Respuesta

45

Primero ordene las teclas por el valor asociado. Luego obtenga los valores (por ejemplo, usando una porción hash).

my @keys = sort { $h{$a} <=> $h{$b} } keys(%h); 
my @vals = @h{@keys}; 

O si tiene una referencia hash.

my @keys = sort { $h->{$a} <=> $h->{$b} } keys(%$h); 
my @vals = @{$h}{@keys}; 
+2

Eso fue fácil. A veces es difícil encontrar esos atajos bonitos. Gracias ikegami. – Moni

+0

Puede ver más información en [función de clasificación en Perl] (http: // stackoverflow.com/questions/6454744/sort-function-in-perl/6454804 # 6454804) –

2
my (@nums, @words); 
do { push @nums, shift @$_; 
    push @words, shift @$_; 
    } 
    foreach sort { $a->[0] <=> $b->[0] } 
      map { [ $h->{ $_ }, $_ ] } keys %$h 
    ; 
+0

¿Funciona? Testet con% h pero no funcionó. – Moni

+0

@Moni, funciona bastante bien, escrito tal como es. si necesita '% h', entonces son solo' keys% h' y '$ h {$ _}' en el mapa. – Axeman

5

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

Para ordenar un hash, comience con las teclas. En este ejemplo, proporcionamos la lista de claves para la función de clasificación que luego las compara ASCIIbetically (lo que puede verse afectado por la configuración de su configuración regional). La lista de salida tiene las teclas en orden ASCIIbético. Una vez que tenemos las claves, podemos revisarlas para crear un informe que enumera las claves en orden ASCIIbético.

my @keys = sort { $a cmp $b } keys %hash; 

foreach my $key (@keys) { 
    printf "%-20s %6d\n", $key, $hash{$key}; 
} 

Sin embargo, podríamos obtener más fantasía en el bloque sort(). En lugar de comparar las claves, podemos calcular un valor con ellas y usar ese valor como comparación.

Por ejemplo, para hacer que nuestro fin informe de mayúsculas y minúsculas, que el uso LC a minúsculas las llaves antes de compararlos:

my @keys = sort { lc $a cmp lc $b } keys %hash; 

Nota: si el cómputo es caro o el hash tiene muchos elementos, es posible quiero ver la Transformada Schwartzian para almacenar en caché los resultados del cálculo.

Si, en cambio, queremos ordenar por el valor hash, usamos la tecla hash para buscarlo. Todavía obtenemos una lista de claves, pero esta vez están ordenadas por su valor.

my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash; 

A partir de ahí podemos volvernos más complejos. Si los valores hash son los mismos, podemos proporcionar una ordenación secundaria en la tecla hash.

my @keys = sort { 
$hash{$a} <=> $hash{$b} 
or 
"\L$a" cmp "\L$b" 
} keys %hash; 
+2

Nit: 'lc ($ a) cmp lc ($ b)', que también escribiste como '" \ L $ a "cmp" \ L $ b "', no siempre hará lo correcto. Desea 'fc ($ a) cmp fc ($ b)' ('" \ F $ a "cmp" \ F $ b "'). Disponible desde 5.16. – ikegami

Cuestiones relacionadas