在Perl中按值对哈希散列进行排序的问题

时间:2014-03-11 08:28:20

标签: perl sorting hash

我对哈希的哈希缺乏经验 - 所以我希望有人可以帮助一个新手...... 我有以下多级哈希:

$OCRsimilar{$ifocus}{$theWord}{"form"} = $theWord;
$OCRsimilar{$ifocus}{$theWord}{"score"} = $OCRscore;
$OCRsimilar{$ifocus}{$theWord}{"distance"} = $distance;
$OCRsimilar{$ifocus}{$theWord}{"similarity"} = $similarity;
$OCRsimilar{$ifocus}{$theWord}{"length"} = $ilength;
$OCRsimilar{$ifocus}{$theWord}{"frequency"} = $OCRHashDict{$ikey}{$theWord};

稍后,我需要根据分数值对每个二级元素($ theWord)进行排序。我尝试了各种各样的事情,但到目前为止都失败了。问题似乎是排序在哈希引入了新的空元素。 我做了什么(例如 - 我确定这远非理想):

my @flat = ();
foreach my $key1 (keys { $OCRsimilar{$ifocus} }) {
    push @flat, [$key1, $OCRsimilar{$ifocus}{$key1}{'score'}];
}

for my $entry (sort { $b->[1] <=> $a->[1] } @flat) {
    print STDERR "@$entry[0]\t@$entry[1]\n";
}

如果我使用Data :: Dumper检查内容,则哈希包含例如:

  'uroadcast' => {
                 'HASH(0x7f9739202b08)' => {},
                 'broadcast' => {
                                'frequency' => '44',
                                'length' => 9,
                                'score' => '26.4893274374278',
                                'form' => 'broadcast',
                                'distance' => 1,
                                'similarity' => 1
                              }
               }

如果我没有进行排序,那么散列很好。发生了什么事? 提前感谢任何指针...!

2 个答案:

答案 0 :(得分:1)

告诉sort要排序的内容。不需要其他技巧。

#!/usr/bin/perl
use warnings;
use strict;

my %OCRsimilar = (
                  focus => {
                            word => {
                                     form       => 'word',
                                     score      => .2,
                                     distance   => 1,
                                     similarity => 1,
                                     length     => 4,
                                     frequency  => 22,
                                    },
                            another => {
                                        form       => 'another',
                                        score      => .01,
                                        distance   => 1,
                                        similarity => 1,
                                        length     => 7,
                                        frequency  => 3,
                                       },
                           });

for my $word (sort { $OCRsimilar{focus}{$a}{score} <=> $OCRsimilar{focus}{$b}{score} }
                   keys %{ $OCRsimilar{focus} }
             ) {
    print "$word: $OCRsimilar{focus}{$word}{score}\n";
}

指针:perlreftutperlrefsort

答案 1 :(得分:0)

对我来说似乎有些怀疑的是这个结构:

foreach my $key1 (keys { $OCRsimilar{$ifocus} }) {

尝试解除引用哈希值,因此它变为:

foreach my $key1 (keys %{ $OCRsimilar{$ifocus} }) {

否则,您似乎正在创建一个匿名哈希并获取它的密钥,相当于此代码:

foreach my $key1 (keys { $OCRsimilar{$ifocus} => undef }) {

因此,我认为$key1在循环内等于$OCRsimilar{$ifocus}。然后,我认为Perl会在遇到$OCRsimilar{$ifocus}{$key1}时进行自动生成,并将哈希引用$OCRsimilar{$ifocus}添加为自己的新密钥。

如果您use warnings;,该计划应该投诉Odd number of elements in anonymous hash

但是,我不明白为什么Perl不进行进一步的自动生成并添加'score'作为密钥,在数据转储中显示'HASH(0x7f9739202b08)' => { 'score' => undef },之类的内容。