[英]Compare values of keys across multiple hashes in Perl
我有一组哈希(使用Tie :: IxHash保留键序列),我想比较每个键的值。 哈希数可以变化。 例如,我想计算为键“ 1”分配值“ 1”和“ 0”的次数。 我知道,如果我将哈希值放入一个哈希值数组中然后循环遍历它们,应该有一种很好的快速方法来计算值匹配,但是我被卡住了,无法自行解决。
%hash1 = ( 1 => '1',
2 => '1',
3 => '0',
4 => '0',
);
%hash2 = ( 1 => '1',
2 => '1',
3 => '1',
4 => '0',
);
%hash3 = ( 1 => '1',
2 => '1',
3 => '0',
4 => '1',
);
%hash4 = ( 1 => '1',
2 => '0',
3 => '0',
4 => '1',
);
上面的预期结果是:
$key1: $agr1 = 4; $agr0 = 0;
$key2: $agr1 = 3; $agr0 = 1;
$key3: $agr1 = 1; $agr0 = 3;
$key4: $agr1 = 2; $agr0 = 2;
现在,我最终要做的是循环遍历第一个哈希的键,然后将它们与其他每个哈希进行比较,由于明显的原因,这很乏味又愚蠢。
谢谢你的帮助!
更正:我使用的是哈希,而不是哈希引用。 相应地编辑了上面的代码。
您可以在@wanted中输入任何所需的值,从而使结果具有一定的灵活性。 假设您的哈希实际上是哈希引用(在示例中是模糊的):
my @hashes = ($hash1,$hash2,$hash3,$hash4);
my %count;
for my $hash (@hashes) {
$count{ $_ }{ $hash->{$_} }++ for keys %$hash;
}
my @wanted = (1,0);
for my $key (sort { $a <=> $b } keys %count) {
my @result = map { "agr$_ = " . ($count{$key}{$_} || 0) . ';' } @wanted;
print "key $key: @result\n";
}
输出:
key 1: agr1 = 4; agr0 = 0;
key 2: agr1 = 3; agr0 = 1;
key 3: agr1 = 1; agr0 = 3;
key 4: agr1 = 2; agr0 = 2;
伪perl:
# Build a list of refs to your hashes
@a = { \%hash1, \%hash2, ... }
# A container to hold the keys and counts
$keys = {}
# Initialize the key container
for my $h in @a
for my $k in %$h
$keys->{$k} = {0 => 0, 1 => 0} unless exists $keys->{$k}
# Iterate once over all the keys and count occurrences
# assumes input hash values can be only 0 or 1
for my $k in %$keys
for my $h in @a
$keys->{$k}->{$h->{$k}}++ if exists $h->{$k};
首先,您的哈希示例是错误的。 %hash = {}
。
如果您使用%
符号,则需要()
。 如果您需要哈希引用, $hash = {}
。
回到您的问题。 你可以做这样的事情。
通常称为“可见”哈希。
# appending your example above....
my @arr = (\%hash1, \%hash2, \%hash3, \%hash4);
my $seen = {};
# iterate over each hash
for my $hash (@arr) {
# iterate over each key in hash
for my $k (keys %$hash) {
my $val = $hash->{$k};
# check $val and increment
if ($val) {
$seen->{$k}{1}++;
} else {
$seen->{$k}{0}++;
}
}
}
for my $k ( sort keys %$seen ) {
# in case any value is 0/undef
print "$k: 1 = "
. ( $seen->{$k}->{0} ? $seen->{$k}->{0} : 0 ) . " 0 = "
. ( $seen->{$k}->{0} ? $seen->{$k}->{0} : 0 ) . "\n";
}
哪些输出:
$ perl test.pl
1: 1 = 0 0 = 0
2: 1 = 1 0 = 1
3: 1 = 3 0 = 3
4: 1 = 2 0 = 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.