简体   繁体   中英

How do I iterate through a reference to an array of hashes in Perl?

I have a reference to an array of hases that I pass to a subroutine in my perl script

This is the code:

sub mySub {
    (my $resultref) = @_;
    my @list = @$resultref;
    print Dumper(@list);
    foreach my $result (@list) {
        print Dumper($result);
    }
}

And this is the output:

$VAR1 = [
          {
            'portName' => '1.1',
            'ips' => [
                       '192.168.1.242'
                     ],
            'switchIp' => '192.168.1.20',
            'macs' => [
                        '00:16:76:9e:63:47'
                      ]
          },
          {
            'portName' => '1.10',
            'ips' => [
                       '192.168.1.119',
                       '192.168.1.3'
                     ],
            'switchIp' => '192.168.1.20',
            'macs' => [
                        'd0:67:e5:f8:7e:7e',
                        'd0:67:e5:f8:7e:76'
                      ]
          },
        ];

$VAR1 = [
          {
            'portName' => '1.1',
            'ips' => [
                       '192.168.1.242'
                     ],
            'switchIp' => '192.168.1.20',
            'macs' => [
                        '00:16:76:9e:63:47'
                      ]
          },
          {
            'portName' => '1.10',
            'ips' => [
                       '192.168.1.119',
                       '192.168.1.3'
                     ],
            'switchIp' => '192.168.1.20',
            'macs' => [
                        'd0:67:e5:f8:7e:7e',
                        'd0:67:e5:f8:7e:76'
                      ]
          },
        ];

The loop is putting the whole array into the $result variable. I have tried dereferencing it as @$result[0] with no success.

How do I loop those hashes individually?

Thanks!

The arguments to Data::Dumper 's Dumper function should be references. Eg:

use Data::Dumper;
my @array = ([1,2,3], [11,22,33]); # Two-dimensional array
print Dumper @array;               # print array
print Dumper \@array;              # print reference to array

The output:

$VAR1 = [
          1,
          2,
          3
        ];
$VAR2 = [
          11,
          22,
          33
        ];

$VAR1 = [
          [
            1,
            2,
            3
          ],
          [
            11,
            22,
            33
          ]
        ];

The second print gives us the entire structure in one variable. When you print the array directly, it expands into all its elements, so...

print Dumper @array;

Is equivalent to:

print Dumper $array[0], $array[1], ..., $array[$#array];

So, in your case, just do:

sub mySub {
    my ($resultref) = @_;
    print Dumper $resultref;
}

Accessing the inner variables:

Just take a look at Data::Dumper 's output:

$VAR1 = [    # bracket denotes start of an array ref
          {  # curly brackets = hash ref
            'portName' => '1.1',
            'ips' => [
                       '192.168.1.242'
                     ],
            'switchIp' => '192.168.1.20',
            'macs' => [
                        '00:16:76:9e:63:47'
                      ]
          }, # hash ref ends, comma = new array element begins
          {  # new hash ref 
            'portName' => '1.10',
            'ips' => [
                       '192.168.1.119',
                       '192.168.1.3'
                     ],
            'switchIp' => '192.168.1.20',
            'macs' => [
                        'd0:67:e5:f8:7e:7e',
                        'd0:67:e5:f8:7e:76'
                      ]
          }, # end of hash
        ];   # end of array

Important to note here is that all elements of an array, and all the values of a hash are scalars. Therefore, all hashes and arrays can easily be broken up into a list of scalars.

for my $aref (@$resultref) {  # starting array ref
    for my $aref2 (@$aref) {  # second level array ref
        for my $href (@$aref2)  # here begins the hash
            local $\ = "\n";    # add newline to print for simplicity
            print $href->{portName};    # printing a scalar
            print for @{$href_>{ips}};  # printing an array ref w post-script loop
            print $href->{switchIp};
            print for @{$href->{macs}};
        }
    }
}

Note the use of the arrow operator to dereference a reference. If you have a hash or array you would do $array[0] or $hash{$key} , but by using a reference, you "point" to the address contained in the reference instead: $array->[0] or $hash->{$key} .

The parameter passed to mySub is a reference to an array of arrayrefs. To iterate over the nested arrays you could do:

sub mySub {
    my ($resultref) = @_;
    for my $result (@$resultref) {
        my @list = @$result; # array of hashrefs
        ...
    }        
}

I have a reference to an array of hases

No, you've passed in a reference to an array of references to an array of hashes.

If you remove that outer level of indirection then your code works as desired.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM