【发布时间】:2012-12-07 23:34:13
【问题描述】:
我已经浏览了很多网络以寻找解决方案,但我找不到满足我需求的任何东西。
我有一个很大的单词列表,每个单词都附有值
例子:
my %list = (
word => 10,
xword => 15,
yword => 1
)
列表还在继续,但我希望能够返回对应值最高的前 5 个哈希元素
【问题讨论】:
我已经浏览了很多网络以寻找解决方案,但我找不到满足我需求的任何东西。
我有一个很大的单词列表,每个单词都附有值
例子:
my %list = (
word => 10,
xword => 15,
yword => 1
)
列表还在继续,但我希望能够返回对应值最高的前 5 个哈希元素
【问题讨论】:
use strict;
use warnings;
sub topN {
my ($N, %list) = (shift, @_);
$N = keys %list if $N > keys %list;
return (sort { $list{$b} <=> $list{$a} } keys %list)[0..$N-1];
}
my %list = ( word => 10, xword => 15, yword => 1, zword => 4);
print join (",", topN(5, %list)), "\n";
输出:
xword,word,zword,yword
【讨论】:
[0..4] 没有?
splice 在丢弃它之前不必要地修改了@list。您还不必要地修改了@_。
这可以满足您的需求。请注意,如果您的哈希值少于五个元素,它将引发Use of uninitialized value 警告,您可能需要添加代码来满足这一要求。它也是低效的,因为它对整个散列进行排序,而不是只查找前五个值。这是否是一个问题取决于您的情况。
use strict;
use warnings;
my %list = (
word => 10,
xword => 15,
yword => 1,
);
my @top5 = (sort { $list{$b} <=> $list{$a} } keys %list)[0..4];
print "$_\n" for @top5;
输出
xword
word
yword
【讨论】:
[0..4] 切片被内存浪费。在这种情况下,这是不正确的还是有关系?
%list 的大小。如果数据巨大,那么内存可能是一个问题,但您也希望对前 N 个项目进行选择排序,而不是对整个事物进行排序。
use strict;
use warnings;
my %list = (
word => 10,
xword => 15,
yword => 1,
);
my @top5 = sort { $list{$b} <=> $list{$a} } keys %list;
splice(@top5, 5) if @top5 > 5;
print "$_\n" for @top5;
【讨论】:
if @top5 > 5 可以在不添加警告的情况下在 5.16+ 中删除。