如何按值从哈希中获取顶级密钥



我有一个哈希,我按照从大到小的值进行排序。我该如何进入前五名?这里有一篇关于只获取一个值的帖子。

在Perl中,从散列中获得具有最高值的密钥的最简单方法是什么?

我理解这一点,比如说,获取这些值将它们添加到数组中,删除哈希中的元素,然后重新执行该过程?

看起来应该有一个更简单的方法来做这件事然后。

我的哈希叫做%words。

编辑取出代码作为问题的答案,而不需要它。

您的问题是如何从哈希中获得五个最高值。你有这个代码:

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

您已排序的哈希键所在的位置。从那里拿走五把最上面的钥匙?

my @highest = splice @keys, 0, 5;  # also deletes the keys from the array
my @highest = @keys[0..4];         # non-destructive solution

还有一些关于你的代码的评论:

open( my $filehandle0, '<', $file0 ) || die "Could not open $file0n";

最好在die语句中包含错误消息$!,以获取打开失败原因的有价值信息。

for (@words) {
s/[,|.|!|?|:|;|"]//g;
}

正如我在评论中所说,您不需要转义字符或在字符类括号中使用替换。使用任一:

s/[,.!?:;"]//g for @words;   #or
tr/,.!?:;"//d  for @words;

下一部分有点奇怪。

my @stopwords;
while ( my $line = <$filehandle1> ) {
chomp $line;
my @linearray = split( " ", $line );
push( @stopwords, @linearray );
}
for my $w ( my @stopwords ) {
s/bQ$wEB//ig;
}

你从文件中读到了停止语。。。然后从$_中删除停止语?此时您是否正在使用$_?此外,您正在循环头中重新声明@stopwords数组,这实际上意味着您的新数组将为空,并且您的循环将永远不会运行。这个错误似乎是无声的,所以你可能永远不会注意到。

my %words = %words_count;

在这里,您制作了一个%words_count的副本,它似乎是多余的,因为您再也不用它了。如果你有一个大散列,这可能会降低性能。

my $key_count = 0;
$key_count = keys %words;

这可以在一行中完成:my $key_count = keys %words。在我看来,可读性更强。

$value_count = $words{$key} + $value_count;

也可以缩写为+=运算符:$value_cont += $words{$key}

你使用严格和警告是非常好的。

如果性能不是的大问题

(sort {$words{$a} <=> $words{$b}} keys %words)[0..4])

如果你绝对需要杀手级的速度,那么在5次迭代后终止的选择排序可能是最适合你的。

my @results;
for (0..4) {
my $maxkey;
my $max = 0;
for my $key (keys %words){
if ($max < $words{$key}){
$maxkey = $key;
$max = $words{$key};
}
}
push @results, $maxkey;
delete $words{$maxkey};
}
say join(","=>@results);

有CPAN模块,Sort::Key::Top。它有一个直接的接口和一个高效的XS实现:

use Sort::Key::Top qw(rnkeytop);
my @results = rnkeytop { $words{$_} } 5 => keys %words;

最新更新