您好我是Perl的新手并且在初学者阶段请帮忙 我有一个哈希
%hash = { a => 2 , b=>6, a=>4, f=>2, b=>1, a=>1}
我希望输出为
新哈希应该是
%newhash = { a => 7, b=>7,f =>2}
我该怎么做?
计算我正在做的哈希键的频率
foreach $element(sort keys %hash) {
my $count = grep /$element/, sort keys %hash;
print "$element comes in $count times \n";
}
但通过这样做,我得到输出:
a comes 1 times
b comes 1 times
a comes 1 times
f comes 1 times
b comes 1 times
a comes 1 times
这不是我想要的。
如何获得重复键的正确频率数?如何添加这些重复键的值并存储在新哈希中?
答案 0 :(得分:6)
根据定义,哈希不能多次使用相同的哈希键。您可能希望将初始数据存储在不同的数据结构中,例如二维数组:
use strict;
use warnings;
use Data::Dumper;
my @data = ( [ a => 2 ],
[ b => 6 ],
[ a => 4 ],
[ f => 2 ],
[ b => 1 ],
[ a => 1 ],
);
my %results;
for my $value (@data) {
$results{$value->[0]} += $value->[1];
}
print Dumper %results;
# $VAR1 = 'a';
# $VAR2 = 7;
# $VAR3 = 'b';
# $VAR4 = 7;
# $VAR5 = 'f';
# $VAR6 = 2;
那说,其他错误的事情:
%hash = { a => 2 , b=>6, a=>4, f=>2, b=>1, a=>1}
你不能这样做,它将hashref({}
)分配给一个哈希。使用%hash = ( ... )
或$hashref = { ... }
。
答案 1 :(得分:2)
索:
我已经重新编辑了你的帖子,以帮助格式化阅读。研究Markdown Editing Help Guide,这将使您的帖子更清晰,更容易理解。以下是一些提示:
按原始帖子上的“编辑”,您可以看到我做了哪些更改。
现在发表你的帖子。我不确定我理解您的数据。如果您的数据是哈希值,则键将是唯一的。您不能在哈希中使用重复键,那么您的数据来自哪里?
例如,如果你是从每行两个数字的文件中读取它,你可以这样做:
use autodie;
use strict;
use warnings;
open (my $data_fh, "<", "$fileName");
my %hash;
while (my $line = <$data_fh>) {
chomp $line;
my ($key, $value) = split /\s+/, $line;
$hash{$key}++;
}
foreach my $key (sort keys %hash) {
print "$key appears $hash{$key} times\n";
}
前三行是Perl pragmas。它们改变了Perl的运作方式:
use autodie
:这告诉程序在某些情况下死亡,例如当您尝试打开不存在的文件时。这样,我就不必检查open
语句是否有效。use strict
:这确保您在使用变量之前必须声明变量,这有助于消除90%的Perl错误。您使用my
在大多数情况下声明变量 。用my
声明的变量最后在声明它们的块中。这就是为什么my %hash
必须在while块之前声明的原因。否则,一旦循环完成,变量将变为未定义。use warnings
:Perl会在某些条件下生成警告。例如,您尝试打印出没有用户设置值的变量。第一个循环只是逐行浏览我的数据并计算密钥的出现次数。第二个循环打印出结果。