Причиной возникновения трудностей является оператор, <=>
- это числовое сравнение, cmp
- это по умолчанию , и это сравнение строк.
$ perl -E'say for sort qw/01 1 02 200/';
01
02
1
200
С небольшой модификацией мы получаем нечто гораздо ближе к правильному:
$ perl -E'say for sort { $a <=> $b } qw/01 1 02 200/';
01
1
02
200
Однако в вашем случае вам необходимо удалить не цифры.
$ perl -E'say for sort { my $s1 = $a =~ m/(\d+)/; my $s2 = $b =~ /(\d+)/; $s1 <=> $s2 } qw/01 1 02 200/';
01
1
02
200
Вот оно красивее:
sort {
my $s1 = $a =~ m/(\d+)/;
my $s2 = $b =~ /(\d+)/;
$s1 <=> $s2
}
Это не безупречно, но должно дать вам хорошее представление о вашей проблеме с сортировкой.
Да, и как следствие, Shcwartzian Transform решает другую проблему: он останавливает вас от необходимости запускать сложную задачу (в отличие от той, которая вам нужна - регулярное выражение) несколько раз в алгоритме поиска. Это требует затрат памяти для кеширования результатов (что не является неожиданным). По сути, вы выполняете сопоставление входных данных проблемы с выходными данными (обычно в массиве) [$input, $output]
, а затем сортируете по выходным данным $a->[1] <=> $b->[1]
. Теперь, когда ваш материал отсортирован, вы возвращаетесь обратно, чтобы получить исходные данные $_->[0]
.
map $_->[0],
sort { $a->[1] <=> $b->[1] }
map [ $_, fn($_) ]
, qw/input list here/
;
Это круто, потому что он такой компактный и в то же время очень эффективный.