如何维护我添加到Perl哈希的键的顺序?

Cth*_*har 20 perl hash data-structures perl-data-structures

如何在使用以下程序中的哈希计算实际列表的顺序后维护实际列表的顺序?例如,<DATA>

a
b
e
a
c 
d 
a
c
d
b
etc.
Run Code Online (Sandbox Code Playgroud)

使用哈希,我计算每个元素的出现次数.

我想要的是:

a  3
b  2
e  1
c  2
d  2
Run Code Online (Sandbox Code Playgroud)

但是以下程序显示了我的情况.

my (%count, $line, @array_1, @array_2);
while ($line = <DATA>) {
    $count{$line}++ if ( $line =~ /\S/ );
}
@array_1 = keys(%count);
@array_2 = values(%count);
for(my $i=0; $i<$#array_1; $i++)
{
   print "$array_1[$i]\t $array_2[$i]";
}
Run Code Online (Sandbox Code Playgroud)

mir*_*rod 34

哈希不是订购的,但像往常一样,CPAN提供了一个解决方案:Tie :: IxHash

use Tie::IxHash;
my %count;
tie %count, 'Tie::IxHash';

while ($line = <DATA>) {
$count{$line}++ if ( $line =~ /\S/ );
}

while( my( $key, $value)= each %count) {
    print "$key\t $value"; 
}
Run Code Online (Sandbox Code Playgroud)


mob*_*mob 15

散列表中的数据按密钥的散列码的顺序存储,对于大多数目的而言,其类似于随机顺序.您还希望存储每个键的第一个外观的顺序.这是解决此问题的一种方法:

my (%count, $line, @display_order);
while ($line = <DATA>) {
    chomp $line;           # strip the \n off the end of $line
    if ($line =~ /\S/) {
        if ($count{$line}++ == 0) {
            # this is the first time we have seen the key "$line"
            push @display_order, $line;
        }
    }
}

# now @display_order holds the keys of %count, in the order of first appearance
foreach my $key (@display_order)
{
    print "$key\t $count{$key}\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言这是比使用Tie :: IxHash更好的解决方案,我认为这超出了OP的原始需求.它更适合使用键的显示顺序,如本答案中所示,或者使用`foreach my $ key(sort keys%count){...}` (3认同)

bri*_*foy 10

perlfaq4的回答"如何让我的哈希记住我将元素放入其中的顺序?"


如何让哈希记住我将元素放入其中的顺序?

使用CPAN中的Tie :: IxHash.

use Tie::IxHash;

tie my %myhash, 'Tie::IxHash';

for (my $i=0; $i<20; $i++) {
    $myhash{$i} = 2*$i;
    }

my @keys = keys %myhash;
# @keys = (0,1,2,3,...)
Run Code Online (Sandbox Code Playgroud)


Hyn*_*dil 6

只是:

my (%count, @order);
while(<DATA>) {
  chomp;
  push @order, $_ unless $count{$_}++;
}
print "$_ $count{$_}\n" for @order;
__DATA__
a
b
e
a
c
d
a
c
d
b
Run Code Online (Sandbox Code Playgroud)


G. *_*ito 5

另一种选择是David Golden的(@xdg)简单的纯perl Hash::Ordered模块.您获得了顺序,但它更慢,因为哈希成为幕后的对象,并且您使用方法来访问和修改哈希元素.

有些基准测试可以量化模块比常规哈希值慢多少,但它是一种很酷的方式,可以在小脚本中使用键/值数据结构,并且在这种应用程序中足够快.该文档还提到了其他几种排序哈希的方法.