如何计算重复键并将重复键的所有值一起添加到非重复键的新哈希?

时间:2011-11-11 20:11:36

标签: perl hash key duplicates

您好我是Perl的新手并且在初学者阶段请帮​​忙 我有一个哈希

%hash = { a => 2 , b=>6, a=>4, f=>2, b=>1, a=>1}

我希望输出为

  • a来了3次
  • b来了2次
  • f来一次

新哈希应该是

%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

这不是我想要的。

如何获得重复键的正确频率数?如何添加这些重复键的值并存储在新哈希中?

2 个答案:

答案 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,这将使您的帖子更清晰,更容易理解。以下是一些提示:

  • 将代码缩进四个空格。这告诉Markdown不要管它,不要重新格式化。
  • 当你列出一个清单时,把astricks放在前面有一个空格。 Markdown了解它是一个项目符号列表,并将其格式化。

按原始帖子上的“编辑”,您可以看到我做了哪些更改。


现在发表你的帖子。我不确定我理解您的数据。如果您的数据是哈希值,则键将是唯一的。您不能在哈希中使用重复键,那么您的数据来自哪里?

例如,如果你是从每行两个数字的文件中读取它,你可以这样做:

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会在某些条件下生成警告。例如,您尝试打印出没有用户设置值的变量。

第一个循环只是逐行浏览我的数据并计算密钥的出现次数。第二个循环打印出结果。