我有一个哈希,我按最大值到最小值排序。如何进入前5名呢?这里有一篇帖子谈到只获得一个值。
What is the easiest way to get a key with the highest value from a hash in Perl?
我明白,这样可以让这些值将它们添加到数组并删除哈希中的元素然后再次执行该过程?
似乎应该有一种更简单的方法来做到这一点。
我的哈希称为%words。
编辑在没有真正需要的情况下回答问题。
答案 0 :(得分:5)
您的问题是如何从哈希值中获取五个最高值。你有这个代码:
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 $file0\n";
最好在您的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/\b\Q$w\E\B//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}
使用严格和警告是非常好的。
答案 1 :(得分:3)
如果表现不是什么大问题
(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);
答案 2 :(得分:1)
有CPAN模块,Sort::Key::Top。 它具有直接的接口和高效的XS实现:
use Sort::Key::Top qw(rnkeytop);
my @results = rnkeytop { $words{$_} } 5 => keys %words;