在下面的程序中,我如何在使用散列计数其出现次数后保持实际列表的顺序?例如,<DATA>
是
a
b
e
a
c
d
a
c
d
b
etc.
使用hash,我计算了每个元素的出现次数。
我想要的是:
a 3
b 2
e 1
c 2
d 2
但下面的程序显示了另一种情况。
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]";
}
7条答案
按热度按时间soat7uwm1#
哈希没有排序,但像往常一样,CPAN提供了一个解决方案:Tie::IxHash
2ekbmq322#
哈希表中的数据是按照键的哈希代码的顺序存储的,这在大多数情况下就像是一个随机的顺序。你还想存储每个键第一次出现的顺序。这里有一种解决这个问题的方法:
qlvxas9a3#
从perlfaq4对“如何让我的哈希记住我把元素放进去的顺序”的回答中可以看出。
我如何让我的哈希记住我把元素放进去的顺序?
使用CPAN中的Tie::IxHash。
mutmk8jj4#
简单地说:
或者作为一个
8qgya5xd5#
另一个选择是大卫戈尔登(@xdg)的简单的纯perl
Hash::Ordered
模块。您获得了顺序,但它较慢,因为散列成为幕后的对象,您使用方法访问和修改散列元素。可能有一些基准测试可以量化这个模块比常规哈希慢多少,但是在小脚本中使用键/值数据结构是一种很酷的方式,并且对我来说在这种应用程序中足够快。文档还提到了其他几种排序哈希的方法。
ars1skjm6#
我并不认为这是一个更好的技术,但我有时会使用它,它可以存储注意到的计数和顺序,而不仅仅是“看到”类型的哈希。
基本上,不是
$count{$line}
有看到的次数,$count{$line}{count}
是看到的次数,$count{$line}{order}
是看到的顺序。cpjpxq1n7#
哈希在Perl中被赋值之前只是数组,所以如果你把它转换为数组,你可以按照它的原始顺序重写它:
如果你这样做,你显然会失去哈希索引的好处。但是由于哈希只是一个数组,你可以通过将数组分配给哈希来创建一个:
这可能只是“使用数组作为索引”解决方案的一个变体,但我认为它更整洁,因为您直接从源数组创建索引,而不是手动输入索引(或以其他方式)。