如何比较嵌套哈希键的计数和存在

时间:2013-08-20 09:02:27

标签: perl

我想获得一个嵌套哈希的键列表,其后续键是

  1. 不等于2或
  2. 这些键不​​属于我预定义的键。
  3. 在下面的示例中,所需的输出为“person_2”,“person_3”和“person_4”,因为它们没有正好2个键 OR 密钥不是来自我预定义的密钥:

    #!/usr/bin/perl -w
    use strict;
    use Data::Dumper;
    
    my @array = qw/place name/;
    my %seen; 
    $seen{$_}++ for @array;
    
    my $hash = {
        person_1    => {
            name    => "name_1",
            place   => "place_1",
        },
        person_2    => {
            name    => "name_2",
            place   => "place_2",
            address => "address_2",
        },
        person_3    => {
            name    => "name_1",
        },
        person_4    => {
            who     => "name_1",
            where   => "place_1",
        },
    };
    
    foreach my $a (keys %$hash)
    {
        print $a."\n" if (scalar(keys %{$hash->{$a}}) ne scalar(@array));
        foreach $b (keys %{$hash->{a}})
        {
            print $a."\n" unless $seen{$b};
        }
    }
    

    输出

    person_2
    person_3
    

    以上输出适用于person_2person_3,因为它们没有确切的2个键

    但是,我的第二个for循环逻辑也应打印person_4,因为虽然它有2个密钥,但这些密钥不是来自@array的预定义密钥。

    你能告诉我这里我做错了吗。

    -Thanks。

2 个答案:

答案 0 :(得分:2)

你犯了一个错误:

foreach $b (keys %{$hash->{a}})

应该是

foreach $b (keys %{$hash->{$a}})
#   note the $ sign here __^

怎么样:

foreach my $a (keys %$hash) {
    print $a,"\n" if (scalar(keys %{$hash->{$a}}) ne scalar(@array));
    my $found = 0;
    foreach $b (keys %{$hash->{$a}}) {
        $found++ if exists $seen{$b};
    }
    print "$a\n" unless $found;
}

答案 1 :(得分:1)

您可能打算使用keys %{$hash->{$a}}代替keys %{$hash->{a}}。由于没有'a'密钥,因此第二个for循环永远不会启动。

一些一般性建议:

  • 避免使用$a$b作为变量名称,因为它们会逃避限制检查(在您的情况下,$b应该是my $b