清理访问嵌套数据结构的方法

时间:2017-11-21 14:06:56

标签: arrays perl hash dereference

我有一段代码虽然有效,但看起来并不像是干净利落的做法。

我使用以下方法构建结构:

 foreach my $n (@node_list)
 {
    chomp ($n);

    foreach my $c (@cpes)
    {
            my @returned; #Interfaces to CPEs with MED settings
            my @creturned; #General Customer Interfaces

            my ($cust) = $c =~ /([a-zA-Z]+)[_-][a-zA-Z0-9]+/s;
            print "\n\t\tCustomer is $cust\n";

            chomp($c);
            $c = uc $c;
            my ($search) = $c;

            (@returned) = `cat /curr/$n | grep "$search"`;
            if (@returned)
            {
                    my $cust_match = 'interface \"' . $cust;
                    (@creturned) = `cat /curr/$n | egrep -i "$cust_match" | grep -v "$search"`;

            }
            if (@creturned)   #Have we found other CPEs on the same router
            {
                    my ($nf) = $n =~ /([a-zA-Z0-9-]+).cfg/s;

                    my (@interfaces) = map { /([A-Z0-9_]+)/s } @creturned;
                    @interfaces = uniq(@interfaces);

                    unshift  (@interfaces, $c);
                    push (@new_out, {$nf => {$cust => [@interfaces]}});
            }

    }

这将返回:

 $VAR1 = [
        {
          'router-xx-xx' => {
                              '50000' => [
                                               [
                                                 'THXXXXVF_NLXXXX40_1121_2',
                                                 '10x.xx.x.50'
                                               ],
                                               [
                                                 'THXXXPVF_NLXXXX66_1121_1',
                                                 '10x.xx.x.70'
                                               ],
                                               [
                                                 'THXXXXVF_NLXXXX67_1121_2',
                                                 '10x.xx.x.78'
                                               ],

                            }
        },

每个路由器可以有多个VPRN,每个VPRN可以包含多个接口。在上面的例子中,我展示了一个带有一个VPRN的路由器。

但是,在访问上面的元素时,我编写了以下令人费解(但正在工作)的代码:

  foreach my $candidate (@nodes)
    {
            my %node = %{ $candidate };

            foreach my $n (keys %node)
            {
                    print "\nRouter is $n\n";

                    foreach my $cust (keys %{ $node{$n} })
                    {
                            print "Customer on $n is \n" . Dumper $cust;
                            my @intlist = @{$node{$n}{$cust}};

                            my $med_cpe = $intlist[0];      #the CPE that was used to find node

                            {truncated}
                            }
                    }
            }
    }

1 个答案:

答案 0 :(得分:1)

您没有准确解释您对遍历代码的“复杂”,但是通过将数据复制到@intlist%node,您已经使其变得不必要地复杂化了。过度和不一致的缩进也使它笨拙

我会写一些更接近这个

的东西
for my $node ( @nodes ) {

    for my $n ( keys %$node ) {

        print "\nRouter is $n\n";

        for my $cust ( keys %{ $node->{$n} } ) {

            print "Customer on $n is \n" . Dumper \$cust;

            my $med_cpe = $node->{$n}{$cust}[0];
        }
    }
}

如果您不需要$node$n的值,除了访问$med_cpe之外,您根本不需要嵌套数据结构:一个简单的数组就可以了。从表面上看,像这样的数组可以满足您的需求

[
    [
        'router-xx-xx',
        '50000',
        'THXXXXVF_NLXXXX40_1121_2',
        '10x.xx.x.50',
    ],
    [
        'router-xx-xx',
        '50000',
        'THXXXPVF_NLXXXX66_1121_1',
        '10x.xx.x.70',
    ],
    ...
]