Я пишу сценарий, это прочитает мои журналы ftpd и генерирует хеш следующим образом:
$stats = \{
'user1' => {
'files' => 281,
'size' => '3724251021'
},
'user2' => {
'files' => 555,
'size' => '7385856997'
},
'user3' => {
'files' => 235,
'size' => '3716904486'
},
'user4' => {
'files' => 578,
'size' => '8536026929'
}
};
Как я получаю доступ к этому хешу с ключами, отсортированными по размеру?
Я попробовал это, но я получаю ошибку при высказывании не hashref
foreach my $user (sort { $$stats->{$a}->{size} cmp $$stats->{$b}->{size} } keys %$stats) {
blahblahblah...
}
Ваша проблема связана не с сортировкой, а с необычным способом определения $stats
- а именно, как ссылка на хэш-ссылку.
my %hash = (a => 1, b => 2);
my $hash_ref = {c => 3, d => 4};
my $ref_to_hash_ref = \{e => 5, f => 6};
Вы можете использовать либо это:
my $stats = { ... };
foreach my $user (
sort { $stats->{$a}{size} <=> $stats->{$b}{size} }
keys %$stats ) {
...
}
либо это, если вам действительно нужно сделать ссылку на хэш-ссылку:
my $stats = \{ ... };
foreach my $user (
sort { $$stats->{$a}{size} <=> $$stats->{$b}{size} }
keys %$$stats ) {
...
}
Заметьте также, что вы, вероятно, хотите использовать <=>
(числовое сравнение), а не cmp
(строковое сравнение).
Вы можете передать функцию для сортировки, чтобы получить значения в том порядке, в котором вы хотите.
#!/usr/bin/perl
use strict;
my $stats = {
'user1' => {
'files' => 281,
'size' => '3724251021'
},
'user2' => {
'files' => 555,
'size' => '7385856997'
},
'user3' => {
'files' => 235,
'size' => '3716904486'
},
'user4' => {
'files' => 578,
'size' => '8536026929'
}
};
foreach my $key (sort sortBySize (keys(%$stats)))
{
print $key, " => ", $stats->{$key}->{'files'}, " - ",
$stats->{$key}->{'size'}, "\n";
}
exit;
sub sortBySize
{
return $stats->{$b}->{'size'} <=> $stats->{$a}->{'size'};
}
ВЫВОД:
user4 => 578 - 8536026929
user2 => 555 - 7385856997
user1 => 281 - 3724251021
user3 => 235 - 3716904486
Если вы хотите, чтобы они отсортировывались от наименьшего к наибольшему, вам просто нужно переключить $ b и $ a в функции sortBySize:
return $stats->{$a}->{'size'} <=> $stats->{$b}->{'size'};
Кажется, ваша первая строка ошибочна. Это должно быть
$stats = {
. Ваша попытка страдает другой синтаксической ошибкой; вам нужен только один сигил при разыменовании с помощью ->
, и я считаю, что лучше воздержаться от хэш-ключей без пароля:
foreach my $user (sort { $stats->{$a}->{'size'} cmp $stats->{$b}->{'size'} }
keys %$stats) {
# ...
}