我有一个数组哈希,如图所示:
my %hash = (
234 => ["aa", "bb", "aa", "ab", "aa"],
235 => ["aa", "ab", "aa", "bb", "aa"],
236 => ["bb", "aa", "aa", "aa", "bb"],
...
)
我正在尝试浏览每个值的第一个元素并计算bb
的出现次数。
例如,在上面的哈希中,对于显示的所有第一个元素,我有一次出现bb
。我需要将该数字(所有数组的第0个元素中的“bb”的数量)推入一个新数组,然后移动到下一组元素。
对于上面的示例,我将循环遍历数组的所有4个元素,并获得带有(1, 1, 0, 1, 1)
的最终数组。
我在使用正确的代码时遇到了很多麻烦,但还没有找到类似的问题。任何帮助将非常感激。
答案 0 :(得分:5)
一个简单的解决方案:迭代哈希值。对于每个值,迭代数组的成员,并在需要时将结果数组加1:
#!/usr/bin/perl
use warnings;
use strict;
my %hash = (234 => [qw/aa bb aa ab aa/],
235 => [qw/aa ab aa bb aa/],
236 => [qw/bb aa aa aa bb/],
);
my @result;
for my $value (values %hash) {
my $i = 0;
for (@$value) {
$result[$i++] += 'bb' eq $_;
}
}
print "@result\n";
答案 1 :(得分:2)
grep
operator是计算列表中符合特定条件的值的最佳工具。只需迭代哈希值列表的每个条目,即可获得每个元素的计数。
此代码假定每个哈希值数组具有相同的长度,并使用第一个元素的长度作为所有哈希值的大小。
use strict;
use warnings;
my %data = (
234 => [ qw/aa bb aa ab aa/ ],
235 => [ qw/aa ab aa bb aa/ ],
236 => [ qw/bb aa aa aa bb/ ],
);
my @count_bb;
for my $i ( 0 .. $#{(values %data)[0]} ) {
$count_bb[$i] = grep { $_->[$i] eq 'bb' } values %data;
}
print "@count_bb\n";
<强>输出强>
1 1 0 1 1
此替代方法将创建一个散列,其中包含散列值数组中每个不同值的计数。第一步初始化散列以在每个元素中具有正确的零数,第二步增加每个值的计数,因为它在数据中遇到,并且最终循环打印结果%counts
散列的内容
use strict;
use warnings;
my %data = (
234 => [ qw/aa bb aa ab aa/ ],
235 => [ qw/aa ab aa bb aa/ ],
236 => [ qw/bb aa aa aa bb/ ],
);
my %counts;
$counts{$_} = [ (0) x @{(values %data)[0]} ] for map @$_, values %data;
for my $i ( 0 .. $#{(values %data)[0]} ) {
$counts{$_}[$i]++ for map $_->[$i], values %data;
}
while (my ($k, $v) = each %counts) {
printf "%s => (%s)\n", $k, join ', ', @$v;
}
<强>输出强>
ab => (0, 1, 0, 1, 0)
bb => (1, 1, 0, 1, 1)
aa => (2, 1, 3, 1, 2)
答案 2 :(得分:0)
use Data::Dumper;
%hash = (234 => [aa, bb, aa, ab, aa],
235 => [aa, ab, aa, bb, aa],
236 => [bb, aa, aa, aa, bb],
);
do { $i = 0; $element{$i++}->{$_}++ for @{$_}; } for (values %hash);
print Dumper(\%element);
答案 3 :(得分:0)
这是一种更为谨慎(不一定更好)的做事方式。除非维护代码的人知道perl,否则不太清楚。尽管如此,了解map和grep并不是一个坏主意。熟悉它们之后,它们可以帮助您更清楚地了解代码的意图。我建议查看每个解决方案,并尝试弄清楚每个解决方案的工作原理。
此解决方案将处理太短的数组,但根据应用程序的不同,这可能会或可能不是您要查找的内容。
use warnings;
use strict;
use Data::Dumper;
my %hash = (
'234' => [qw(aa bb aa ab aa)],
'235' => [qw(aa ab aa bb aa)],
'236' => [qw(bb aa aa aa bb)],
);
my @result = ();
while ( grep {scalar @{$_}} values %hash ) {
push @result, scalar @{[
grep {$_ eq 'bb'}
map {shift @{$_}}
values %hash
]};
}
print Dumper \@result;