Как я могу сортировать хеш-ключи естественно?

У меня есть хеш Perl, ключи которого начинаются с чисел или являются.

Если я использую

foreach my $key (sort keys %hash) {
    print $hash{$key} . "\n";
}

список может отображаться как

0
0001
1000
203
23

Вместо

0
0001
23
203
1000

Ответы

Ответ 1

foreach my $key (sort { $a <=> $b} keys %hash) {
    print $hash{$key} . "\n";
}

Операция сортировки принимает необязательную сравнительную "подпрограмму" (либо как блок кода, как я сделал здесь, либо имя подпрограммы). Я представил сравнительное сравнение, которое обрабатывает ключи как числа, используя встроенный оператор цифрового сравнения '< = > '.

Ответ 2

Пол отвечает правильно для чисел, но если вы хотите сделать еще один шаг и отсортировать смешанные слова и цифры, как человек, то не будет cmp и <=>. Например...

  9x
  14
  foo
  fooa
  foolio
  Foolio
  foo12
  foo12a
  Foo12a
  foo12z
  foo13a

Sort::Naturally заботится об этой проблеме, предоставляя подпрограммы nsort и ncmp.

Ответ 3

$key (sort { $a <=> $b} keys %hash) 

выполнит трюк

или

$key (sort { $b <=> $a} keys %hash)

убывающая сортировка

или даже

$key (sort { $a <=> $b} values %hash)
$key (sort { $b <=> $a} values %hash)

Ответ 4

Ваша первая проблема - это тело цикла (о чем не упоминается ни один другой ответ).

foreach my $key ( sort keys %hash ) {
    print $hash{$key} . "\n";
}

Мы не знаем, какие ключи %hash, мы просто знаем, что они передаются вам как $key в лексическом порядке внутри цикла. Затем вы используете ключи для доступа к содержимому хеша, печатая каждую запись.

Значения хэша не выходят в отсортированном порядке, потому что вы сортируете по клавишам.

Вместо этого вы хотите вывести значения в отсортированном порядке, рассмотрите следующий цикл:

foreach my $value ( sort values(%hash) ) {
    printf( "%s\n", $value );
}

Этот цикл печатает значения в следующем порядке:

0
0001
1000
203
23

Чтобы отсортировать их численно, используйте

foreach my $value ( sort { $a <=> $b } values(%hash) ) {
    printf( "%s\n", $value );
}

Это создает

0
0001
23
203
1000

что вы хотели.

Подробнее см. руководство Perl для функции sort и еще много примеров.