【问题标题】:sorting hash values in perl [duplicate]在perl中对哈希值进行排序[重复]
【发布时间】:2012-12-07 23:34:13
【问题描述】:

可能重复:
Perl sorting hash by values in the hash

我已经浏览了很多网络以寻找解决方案,但我找不到满足我需求的任何东西。

我有一个很大的单词列表,每个单词都附有值

例子:

my %list = (
  word => 10,
  xword => 15,
  yword => 1
)

列表还在继续,但我希望能够返回对应值最高的前 5 个哈希元素

【问题讨论】:

    标签: perl sorting hash


    【解决方案1】:
    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
    

    【讨论】:

    • 在什么意义上?你的也一样:)
    • 所以 splice 复制列表但 [0..4] 没有?
    • 您的子例程在没有请求的情况下概括了问题,并且时间太长以至于 Perl 的内联优化不会启动。splice 在丢弃它之前不必要地修改了@list。您还不必要地修改了@_
    • 你的快了 600 毫秒,完成时间大约为 9 秒,我的系统上有 100 万个元素。
    • 这不是比赛
    【解决方案2】:

    这可以满足您的需求。请注意,如果您的哈希值少于五个元素,它将引发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
    

    【讨论】:

    • +1 想出了同样的方法,但担心[0..4] 切片被内存浪费。在这种情况下,这是不正确的还是有关系?
    • @Kenosis:这取决于%list 的大小。如果数据巨大,那么内存可能是一个问题,但您也希望对前 N 个项目进行选择排序,而不是对整个事物进行排序。
    【解决方案3】:
    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 &gt; 5 可以在不添加警告的情况下在 5.16+ 中删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2013-12-04
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多