Perl сортирует хеш, как сортировать по $ hash {$ key} -> {secondkey} - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть функция Perl:

my %d;

$d{"aaaa"}->{t1} = "9:49";
$d{"bbbb"}->{t1} = "9:30";

foreach my $k (sort { ($d{$a}->{t1}) <=> ($d{$b}->{t1}) } keys %d)
{
    print "$k:  $d{$k}->{t1}\n";
}

Я хочу отсортировать по t1, поэтому за 9:30 до 9:49 и хочу получить результат:

bbbb:  9:30
aaaa:  9:49

но результат не подходит.

Кажется, что результат случайный?

C:\tmp>a.pl
bbbb:  9:30
aaaa:  9:49

C:\tmp>a.pl
bbbb:  9:30
aaaa:  9:49

C:\tmp>a.pl
bbbb:  9:30
aaaa:  9:49

C:\tmp>a.pl
aaaa:  9:49
bbbb:  9:30

C:\tmp>a.pl
bbbb:  9:30
aaaa:  9:49

C:\tmp>a.pl
bbbb:  9:30
aaaa:  9:49

C:\tmp>a.pl
bbbb:  9:30
aaaa:  9:49

C:\tmp>a.pl
aaaa:  9:49
bbbb:  9:30

enter image description here

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

<=> для сравнения чисел, но ваши времена имеют двоеточие, которое делает их строками вместо чисел. Один из обходных путей - просто удалить двоеточие, чтобы <=> мог работать с ними в числовом контексте.

use v5.10;

say "$_: $d{$_}->{t1}" for sort { $d{$a}->{t1} =~ s/://r <=> $d{$b}->{t1} =~ s/://r } keys %d;

Модификатор r в подстановке означает возвращение нового значения без изменения старого значения.

0 голосов
/ 08 ноября 2018

Вам нужно использовать cmp вместо <=>, так как вы сравниваете строки. Комментарии верны, и мы должны принять во внимание более 10 часов. Вам нужно использовать sprintf для добавления начального нуля, когда часы меньше 10, чтобы строки были отсортированы правильно.

foreach my $k (sort { sprintf("%05s", ($d{$a}->{t1})) cmp sprintf("%05s", ($d{$b}->{t1})) } keys %d) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...