【问题标题】:how to use foreach loop to do comparison between two arrays of hashes如何使用 foreach 循环在两个哈希数组之间进行比较
【发布时间】:2018-10-25 18:22:52
【问题描述】:

我需要使用 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 

我的哈希1:

'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'
                                ]
                      }


 };

我的哈希2:

$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”...

【问题讨论】:

  • 哈希的键总是相同或可以不同,因为在这里我看到两种情况下的键是相同的,你只是想比较 x1,y1 等的值,而且我不要认为你需要 2 个单独的 foreach 循环来匹配和不匹配,你可以只使用标志并在同一个循环中执行,但最好使用 @MattJacob 建议的 Data:Compare
  • 为什么不能使用Data::Compare 模块?
  • 您可以访问此链接以获取类似答案stackoverflow.com/questions/1273616/…
  • 我还没有了解 Data::Compare 。正如我认为这只能通过使用 foreach 循环来独立比较 x1 和 x1、y1 和 y1 来完成。 @MattJacob
  • 是的,实际上我的想法是使用 1 个 foreach 循环来进行匹配和不匹配。我在上面写了 2 个 foreach 循环只是想让 ppl 知道我只从 ($newx1 == $oldx1) 到 ($newx1 != $oldx1) 进行了一些小的更改。我会更正它。@NileshJain

标签: perl


【解决方案1】:

x1、y1 等...只是散列中的键,因此您可以像获取任何散列这样的键一样获取它们

keys %{$hash1{$newq}}

你不需要让你的代码像你有那么多层的循环一样复杂。以这部分为例……

foreach my $newq (keys %hash1)
{
     foreach my $oldq(keys %hash2)
     {
         if ( $newq eq $oldq)
         {
             # ....
         }
     }
 }

您不需要遍历两个散列,因为您可以测试一个键是否存在于另一个散列中。想象一下,如果你的哈希每个都有 100 个键。您的代码当前使用 %hash1 中的每个键检查 %hash2 中的所有 100 个键,然后再次执行此操作,因此进行了 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}});
    }
}

虽然您声明的哈希值与您的源数据不匹配,但输出看起来并不符合您的预期。我本来希望你的哈希看起来更像下面的 sn-p,所以也许你的文件读取代码也没有像你想要的那样工作?

'Adidas' => {
   'x1' => [
       '99999','88888','55555','77777'
    ]
  };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 2021-12-29
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    相关资源
    最近更新 更多