我需要使用foreach循环在两个哈希数组之间进行比较。但是我真的不知道该怎么做。
我的原始数据:
NewData(file 1)
Puma
77777 33333 44444 55555
Adidas
99999 88888 55555 77777
22222 11111 33333 44444
Brooks
11111 22222 33333 44444
33333 44444 55555 66666
OldData(file 2)
Puma
77777 33333 44444 55555
Adidas
11111 11111 33333 44444
99999 88888 55555 77777
Brooks
11111 22222 33333 44444
33333 44444 55555 66666
我的hash1:
'Adidas' => {
'y1' => [
'88888',
'11111'
],
'x2' => [
'55555',
'33333'
],
'y2' => [
'77777',
'44444'
],
'x1' => [
'99999',
'22222'
]
},
'Puma' => {
'y1' => [
'33333'
],
'x2' => [
'44444'
],
'y2' => [
'55555'
],
'x1' => [
'77777'
]
},
'Brooks' => {
'y1' => [
'22222',
'44444'
],
'x2' => [
'33333',
'55555'
],
'y2' => [
'44444',
'66666'
],
'x1' => [
'11111',
'33333'
]
}
};
我的hash2:
$VAR1 = {
'Adidas' => {
'y1' => [
'11111',
'88888'
],
'x2' => [
'33333',
'55555'
],
'y2' => [
'44444',
'77777'
],
'x1' => [
'11111',
'99999'
]
},
'Puma' => {
'y1' => [
'33333'
],
'x2' => [
'44444'
],
'y2' => [
'55555'
],
'x1' => [
'77777'
]
},
'Brooks' => {
'y1' => [
'22222',
'44444'
],
'x2' => [
'33333',
'55555'
],
'y2' => [
'44444',
'66666'
],
'x1' => [
'11111',
'33333'
]
}
};
我的匹配和不匹配尝试代码:
foreach my $newq (keys %hash1)
{
foreach my $oldq(keys %hash2)
{
if ( $newq eq $oldq)
{
foreach my $newx1(@{$hash1{$newq}{x1}})
{
foreach my $oldx1(@{$hash2{$oldq}{x1}})
{
if ($newx1 == $oldx1)
{
print "$newq\t$newx1\t$oldx1\n";
}
if ($newx1 != $oldx1)
{
print "$newq\t$newx1\t$oldx1\n";
}
}
我的匹配输出
New Old
Adidas 99999 99999
Puma 77777 77777
Brooks 11111 11111
Brooks 33333 33333
我的输出不匹配:
New Old
Adidas 99999 11111
Adidas 22222 11111
Adidas 22222 99999
Brooks 11111 33333
Brooks 33333 11111
匹配所需的输出:
New Old
Puma 77777 33333 44444 55555 77777 33333 44444 55555
Adidas 99999 88888 55555 77777 99999 88888 55555 77777
Brooks 11111 22222 33333 44444 11111 22222 33333 44444
Brooks 33333 44444 55555 66666 33333 44444 55555 66666
Not matching
Adidas 22222 11111 33333 44444 11111 11111 33333 44444
现在我可以获得x1的正确匹配。但是我得到了“不匹配”的错误输出。我对“不匹配”的预期输出是Adidas 22222 11111
,仅因为在新数据和旧数据中都显示了'x1=> 99999'
。而且我不确定如何继续使用“ y1,x2和y2” ...
答案 0 :(得分:1)
x1,y1等...只是哈希中的键,因此您可以像获取任何哈希这样的键一样获得它们
keys %{$hash1{$newq}}
尽管有那么多循环的层,您不必使代码变得如此复杂。以这部分为例...
foreach my $newq (keys %hash1)
{
foreach my $oldq(keys %hash2)
{
if ( $newq eq $oldq)
{
# ....
}
}
}
您不需要遍历两个哈希,因为您可以测试看看另一个哈希中是否存在键。想象一下,如果您的每个哈希都有100个密钥。您的代码当前检查%hash2
中的所有100个键和%hash1
中的每个键,然后再次进行检查,因此进行了20000次测试。如果您这样编写代码...
foreach my $newq (keys %hash1)
{
if(defined($hash2{$newq}))
{
# both hashes have this key
}
else
{
# %hash2 doesn't have the key
}
}
foreach my $newq (keys %hash2)
{
if(!defined($hash1{$newq}))
{
# %hash1 doesn't have the key
}
else
{
# They both do, but we already know that from the first loop
}
}
...它只需要检查两个哈希中的每个键一次,因此只需200次检查。
所以最终完成的代码可能是:
my %nonmatching;
print "Matching\n";
foreach my $outerkey (keys %hash1)
{
if(defined($hash2{$outerkey}))
{
foreach my $innerkey (keys %{$hash1{$outerkey}})
{
if(join(" ",sort @{$hash1{$outerkey}{$innerkey}}) eq join(" ",sort @{$hash2{$outerkey}{$innerkey}}))
{
printf "%-20s %30s %30s\n",$outerkey, join(" ",@{$hash1{$outerkey}{$innerkey}}), join(" ",@{$hash2{$outerkey}{$innerkey}});
}
else
{
$nonmatching{$outerkey}{$innerkey}=1;
}
}
}
else
{
foreach my $innerkey (keys %{$hash1{$outerkey}})
{
$nonmatching{$outerkey}{$innerkey}=1;
}
}
}
foreach my $outerkey (keys %hash2)
{
if(!defined($hash1{$outerkey}))
{
foreach my $innerkey (keys %{$hash2{$outerkey}})
{
$nonmatching{$outerkey}{$innerkey}=1;
}
}
}
print "Nonmatching\n";
foreach my $outerkey (keys %nonmatching)
{
foreach my $innerkey (keys %{$nonmatching{$outerkey}})
{
printf "%-20s %30s %30s\n",$outerkey, join(" ",@{$hash1{$outerkey}{$innerkey}}), join(" ",@{$hash2{$outerkey}{$innerkey}});
}
}
尽管您所声明的哈希值与源数据不匹配,所以输出看起来并不符合您的期望。我本来希望您的哈希看起来更像下面的代码片段,所以也许您的文件读取代码无法按照您的意愿工作?
'Adidas' => {
'x1' => [
'99999','88888','55555','77777'
]
};