Вернуть все пары хэш-ключ / значение с максимальным значением - PullRequest
3 голосов
/ 11 мая 2011

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

Например, учитывая

my %hash = (
    key1 => 2,
    key2 => 6,
    key3 => 6,
);

Я хотел бы создать новый хеш, содержащий:

%hash_max = (
    key2 => 6,
    key3 => 6,
);

Я уверен, что есть много способов сделать это, но я ищу элегантное решение (и возможность учиться!).

Ответы [ 3 ]

7 голосов
/ 11 мая 2011
use List::Util 'max';
my $max = max(values %hash);
my %hash_max = map { $hash{$_}==$max ? ($_, $max) : () } keys %hash;

Или однопроходный подход (аналогично, но немного отличается от другого ответа):

my $max;
my %hash_max;
keys %hash; # reset iterator
while (my ($key, $value) = each %hash) {
    if ( !defined $max || $value > $max ) {
        %hash_max = ();
        $max = $value;
    }
    $hash_max{$key} = $value if $max == $value;
}
1 голос
/ 11 мая 2011
# sort numerically descending
my @topkey = sort {$hash{$b} <=> $hash{$a}} keys %hash;

Затем скопируйте верхние значения в% hash_max с разделителем цикла после последнего максимального значения:

for $key (@topkey) {
    if ($hash{$key} == $hash{$topkey[0]}) {
        $hash_max{$key} = $hash{$key}
    } else { last }
}

ETA: обратите внимание неверующим, что last работает, потому что ключи в @topkey отсортированы, поэтому мы можем разорвать цикл, когда значение больше не похоже на первое. То есть все следующие значения ниже.

1 голос
/ 11 мая 2011

Это делает один проход по данным, но тратит много хеш-записей:

use strict;
use warnings;

my %hash = (
    key1 => 2,
    key2 => 6,
    key3 => 6,
);

my %hash_max = ();
my $max;
foreach my $key (keys %hash) {
        if (!defined($max) || $max < $hash{$key} ) {
                %hash_max = ();
                $max = $hash{$key};
                $hash_max{$key} = $hash{$key};
        }
        elsif ($max == $hash{$key}) {
                $hash_max{$key} = $hash{$key};
        }
}

foreach my $key (keys %hash_max) {
        print "$key\t$hash_max{$key}\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...