2013-05-31 2 views
1

У меня есть следующая структура,% хеш:Perl: Сортировка значений хэша и положить результат в новом хэша, где ключи позиция в рейтинге

$VAR1 = { 
      1 => 5, 
      3 => 1, 
      2 => 4, 
      4 => 9, 

     }; 

Ключи этого хэша представляют собой идентификатор и значения представляют собой номер доступа: id => номер доступа

Я хочу отсортировать его с использованием номера доступа в порядке убывания и сохранить его в другом хэше. Но я хочу, чтобы значения были id на этот раз. Клавиши должны быть позиция в рейтинге: позиция в загребать (от 1 до п) => идентификатор

В данном конкретном случае:

$VAR2 = { 
      1 => 4, 
      2 => 1, 
      3 => 2, 
      4 => 3, 
     }; 

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

ответ

2

Вы можете использовать сортировку в цикле foreach.

my %hash = (
1 => 5, 
3 => 1, 
2 => 4, 
4 => 9, 
); 

my %hash2; 
my $count = 1; 
foreach my $key(sort{$hash{$b} <=> $hash{$a}} keys %hash){ 
    $hash2{$count++} = $key; 
} 

use Data::Dumper; 
print Dumper(\%hash2); 

ИЛИ

Вы можете использовать карту, чтобы сделать зацикливание, как упомянуто Дэвид. Я добавил foreach для простоты.

my %hash2 = map {$count++ => $_} sort{$hash{$b} <=> $hash{$a}} keys %hash; 
+0

спасибо! я запомнил один вкладыш – ado

2

Следующий код сортирует ключи (ids) на основе их соответствующих значений, а затем сопоставляет эти ключи с ранжированием.

use Data::Dumper; 

my %old_hash = (
    1 => 5, 
    3 => 1, 
    2 => 4, 
    4 => 9, 
); 

my $rank = 1; 

my %new_hash 
    = map { $rank++ => $_ } 
    sort { $old_hash{$b} <=> $old_hash{$a} } 
    keys %old_hash; 

print Dumper \%new_hash; 

Это легче понять, если читать карту/сортировать/ключи построить назад:

Во-первых, список всех ключей, второй, сортировать их по значениям они индексируют, третий, наметить новый hash, где ключи являются текущим рангом, а значениями являются ассоциированный идентификатор.

0

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

my @ids_by_desc_access = 
    sort { ... } 
     keys(%accesses_by_id); 

Вы хотите, чтобы они отсортированы по убыванию количества доступов, поэтому мы добавим, что сравнение:

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

Наконец, вы странно хотите использовать хеш в качестве массива.

my %ids_by_desc_access = 
    map { $_+1 => $ids_by_desc_access[$_] } 
     0..$#ids_by_desc_access; 
+0

Я набрал это сразу после того, как вопрос был опубликован задолго до первого ответа, но потом я потерпел поражение компьютера. Поскольку это хороший ответ, я подумал, что все равно опубликую его. – ikegami

+0

или просто 'my% ids_by_desc_access; @ids_by_desc_access {1..keys% access_by_id} = sort {$ access_by_id {$ b} <=> $ access_by_id {$ a}} ключи% access_by_id; ' – ysth

+0

@ysth, его можно сделать в одну строку, но я преподавал процесс найти ответ, а не просто дать ответ. Но спасибо за код. – ikegami

Смежные вопросы