2015-03-23 6 views
0

Допустим, я следующая информация хранится в хэш:Как показать верхние значения из хэша в perl?

kiwi 15 
oranges 25 
cherries 30 
apples 2 
pears 1 

Я хочу написать код, который будет отображаться в нисходящем (по количеству) топ-3 записей. Таким образом, выход должен быть

cherries 30 
oranges 25 
kiwi 15 

Я не могу найти однозначного ответа на этот счет.

+1

Это проблема домашней работы? Я не помню, чтобы когда-либо встречал вопрос, который автор говорит, это домашнее задание, но Stack Overflow прекрасно справляется с домашними заданиями, поэтому я не понимаю сдержанности. Взгляните на [этот пост по теме] (http://meta.stackexchange.com/q/10811), из которого я забираю * «Предоставление ответа, который не помогает учащемуся учиться, не в собственном ученике наилучший интерес "*. Итак, нет, мы не будем делать все для вас; но помощь в порядке – Borodin

ответ

5

Это будет делать, как вы просите. Он использует sort со сравнительным блоком, который сравнивает соответствующее значение хэша каждой клавиши в обратном порядке. Затем каждый из трех первых отсортированных ключей печатается вместе с его значением из хэша.

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

use strict; 
use warnings; 

my %data = qw/ 
    kiwi  15 
    oranges 25 
    cherries 30 
    apples 2 
    pears  1 
/; 

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

for my $key (@sorted_keys[0..2]) { 
    print "$key $data{$key}\n"; 
} 

выход

cherries 30 
oranges 25 
kiwi 15 

Update

Для более общего решения модуль (неядерный) List::UtilsBy предлагает ряд полезных функций, которые предлагают сортировки, максимумы и минимумы в зависимости от списка объектов. Это позволяет мне писать выше, как

use List::UtilsBy qw/ nsort_by /; 

my @sorted_keys = nsort_by { $data{$_} } keys %data; 

for my $key ((reverse @sorted_keys)[0..2]) { 
    print "$key $data{$key}\n"; 
} 

или, если вы предпочитаете обратный в другом месте

use List::UtilsBy qw/ rev_nsort_by /; 

my @sorted_keys = rev_nsort_by { $data{$_} } keys %data; 

for my $key (@sorted_keys[0..2]) { 
    print "$key $data{$key}\n"; 
} 

Заметим, что разница между модуля sort_by и nsort_by эквивалентна разнице между cmp и <=>, соответственно.

Обе эти альтернативы генерируют идентичный выход оригиналу выше

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