Подтвердить что ты не робот

Как сортировать хеш perl по значениям и заказывать ключи соответственно (возможно, в двух массивах)?

В Perl я хочу сортировать ключи хэша по значению, численно:

{
  five => 5
  ten => 10
  one => 1
  four => 4
}

создает два массива:

(1,4,5,10) and (one, four, five, ten)

И затем я хочу нормализовать массив значений таким образом, чтобы числа были последовательными:

(1,2,3,4)

Как это сделать?

4b9b3361

Ответ 1

Сначала отсортируйте ключи по соответствующему значению. Затем получите значения (например, используя хэш-срез).

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

Или, если у вас есть хеш-ссылка.

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

Ответ 2

Как сортировать хэш (необязательно по значению вместо ключа)?

Чтобы отсортировать хэш, начните с ключей. В этом примере мы приводим список ключей функции сортировки, который затем сравнивает их ASCIIbetically (на которые могут влиять ваши настройки локали). Выходной список имеет ключи в ASCII-битезированном порядке. После того, как у нас есть ключи, мы можем пройти через них, чтобы создать отчет, в котором перечислены ключи в ASCII-формате.

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

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

Мы могли бы получить больше фантазии в блоке sort(). Вместо сравнения ключей мы можем вычислить значение с ними и использовать это значение в качестве сравнения.

Например, чтобы сделать наш порядок отчетов нечувствительным к регистру, мы используем lc для прокрутки ключей до их сравнения:

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

Примечание. Если вычисление дорогостоящее или хеш имеет много элементов, вы можете посмотреть на преобразование Шварца, чтобы кэшировать результаты вычислений.

Если мы хотим сортировать по хэш-значению вместо этого, мы используем хеш-ключ для поиска. Мы по-прежнему получаем список ключей, но на этот раз они упорядочены по их значению.

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

Оттуда мы можем усложниться. Если значения хэша одинаковы, мы можем предоставить вторичный сорт хэш-ключа.

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

Ответ 3

См. раздел "Вопросы по Perl", озаглавленный "Как сортировать хеш (необязательно по значению вместо ключа)"

http://perldoc.perl.org/perlfaq4.html#How-do-I-sort-a-hash-%28optionally-by-value-instead-of-key%29?

Вы также можете использовать perldoc -q для поиска часто задаваемых вопросов на вашем компьютере, например, в perldoc -q sort, как я нашел ваш ответ.

Ответ 4

my ( @nums, @words );
do { push @nums,  shift @$_; 
     push @words, shift @$_; 
   }
    foreach sort { $a->[0] <=> $b->[0] } 
            map  { [ $h->{ $_ }, $_ ] } keys %$h
   ;