2012-06-05 8 views

risposta

45

Prima ordinare le chiavi con il valore associato. Quindi ottieni i valori (ad esempio usando una slice hash).

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

Oppure se si dispone di un riferimento hash.

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

È stato facile. A volte è difficile venire con quelle belle scorciatoie. Grazie Ikegami. – Moni

+0

È possibile visualizzare maggiori informazioni in [funzione di ordinamento in Perl] (http: // stackoverflow.it/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

Funziona? Testet con% h ma non ha funzionato. – Moni

+0

@Moni, funziona abbastanza bene, scritto così com'è. se hai bisogno di '% h', allora sono solo' chiavi% h' e '$ h {$ _}' nella mappa. – Axeman

5

Come si ordina un hash (facoltativamente in base al valore anziché al tasto)?

Per ordinare un hash, iniziare con i tasti. In questo esempio, forniamo l'elenco delle chiavi alla funzione di ordinamento che quindi le confronta in modo ASCII (che potrebbe essere influenzato dalle impostazioni locali). L'elenco di output ha le chiavi in ​​ordine ASCIIbetic. Una volta che abbiamo le chiavi, possiamo esaminarle per creare un rapporto che elenca le chiavi in ​​ordine ASCIIbetico.

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

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

Tuttavia, nel blocco sort() si potrebbe ottenere di più. Invece di confrontare le chiavi, possiamo calcolare un valore con esse e usare quel valore come confronto.

Per esempio, per rendere il nostro ordine rapporto case-insensitive, usiamo lc in minuscolo le chiavi prima confrontandoli:

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

Nota: se il calcolo è costoso o l'hash ha molti elementi, si può vuoi guardare la Trasformata di Schwartz per mettere in cache i risultati del calcolo.

Se invece vogliamo ordinare per valore hash, usiamo il tasto hash per cercarlo. Abbiamo ancora una lista di chiavi, ma questa volta sono ordinate in base al loro valore.

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

Da lì possiamo diventare più complessi. Se i valori hash sono gli stessi, possiamo fornire un ordinamento secondario sulla chiave hash.

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

Nit: 'lc ($ a) cmp lc ($ b)', che hai anche scritto come '" \ L $ a "cmp" \ L $ b "', non farà sempre la cosa giusta. Vuoi 'fc ($ a) cmp fc ($ b)' ('" \ F $ a "cmp" \ F $ b "'). Disponibile dal 5.16. – ikegami

Problemi correlati