取消引用perl中的嵌套哈希

时间:2016-03-03 19:23:32

标签: perl hash hashmap

#!/usr/bin/perl

use strict;
use warnings;

my %ani_hash = (
    'machine_results' => [
        {
            'status'  => 'Failed install',
            'machine' => '23.73.134.235',
            'seconds' => '20',
            'try'     => '1'
        },
        {
            'status'  => 'Failed install',
            'machine' => '23.73.134.140',
            'seconds' => '20',
            'try'     => '1'
        }
    ],
    'description' => 'MC-5897'
);

get_elements( \%ani_hash );

sub get_elements
{
    my $hashref1 = shift;

    my %hashref2 = %$hashref1;
    print "%hashref1\n";

    foreach my $machineresult ( keys %hashref2 ) {
        foreach my $machineresult2 ( keys %{ $hashref2{$machineresult} } ) {
            print "$hashref2{$machineresult}{$machineresult2}\n";
        }
    }
}

Output: 

    HASH(0x1e9fe58)
    Not a HASH reference at ./hashref.pl line 62.
    Can't use string ("MC-5897") as a HASH ref while "strict refs" in use at ./hashref.pl line 62.

我想循环遍历所有键值对并获取它们的值。 我不想使用dumper方法来获取值,我想通过循环方法获取这些值。任何帮助,将不胜感激。谢谢

我这样做是为了解决问题并获取'machine_results'的内容。

print "description: $hashref2{description}\n";

foreach my $machineresult( sort keys%hashref2){
    foreach my $array (@{ $hashref2{$machineresult} }){
        foreach my $array1( sort keys%{$array} ){
            print "key is $array1 and it's value is $array->{$array1}`",
                  "enter code here`\n";    
        }
        print "\n";
    }
}

2 个答案:

答案 0 :(得分:1)

我认为您的%ani_hash总是有2个元素machine_resultsdescription,而您只想迭代machine_results中的数组(ref)。如果是这样,以下内容可以提供帮助:

sub get_elements
{
    my $hashref = shift;

    print "Description: $hashref->{description}\n";

    my $count=0;
    foreach my $result ( @{ $hashref->{machine_results} } ) {
        print $count++, ': ';
        foreach my $key ( sort keys %{$result} ) {
            print "$key=$result->{$key}, ";
        }
        print "\n";
    }
}

get_elements( \%ani_hash );

输出:

Description: MC-5897
0: machine=23.73.134.235, seconds=20, status=Failed install, try=1, 
1: machine=23.73.134.140, seconds=20, status=Failed install, try=1, 

说明:

  • $hashref->{machine_results}是包含机器结果的arrayref。
  • @{ $hashref->{machine_results} }将其解引用到您可以迭代的数组,所以
  • $result是这些数组项之一,而这些数组项又是对哈希
  • 的引用
  • %{$result}取消引用哈希,我们迭代(排序)键

当然,这假设你的数据结构就是这样,即machine_results包含一个带有hashrefs的arrayref。

答案 1 :(得分:0)

您的代码未正确解压缩嵌套哈希。对于散列%h = ('key' => [1, 2]),与key关联的值是对(匿名)数组的引用,因此是标量。请参阅最后的链接。

要获取数组的内容,我们需要取消引用它。那些数组元素本身就是hashrefs,它们也需要被解除引用

sub get_elements 
{    
    my %hash = %{ $_[0] };
    print "description: $hash{'description'}\n";
    foreach my $mach_res (keys %hash)
    {   
        next if $mach_res eq 'description';
        foreach my $elem ( @{$hash{$mach_res}} ) { 
            my %mach_detail = %$elem;
            print "\t---\n";
            foreach my $key (sort keys %mach_detail) {
                print "\t$key => $mach_detail{$key}\n";
            }   
        }           
    }   
}

hashref用于获取新的“in-sub”副本%hash。这是一些防止错误的保护,因为原始数据无法更改。但是,如果您希望subs直接更改其引用的数据,那么您需要使用引用本身。这打印

description: MC-5897
        ---
        machine => 23.73.134.235
        seconds => 20
        status => Failed install
        try => 1
        ---
        machine => 23.73.134.140
        seconds => 20
        status => Failed install
        try => 1

代码将处理“描述”以外的任何其他键。如果您想对齐打印输出,可以先拉出其中一个键(单词)的最大长度,然后使用printf获取详细信息。

use List::Util qw(max);
foreach my $elem ( @{$hash{$mach_res}} ) {
    my %mach_detail = %$elem;
    my $max_len = max( map { length } keys %mach_detail );
    print "\t---\n";
    foreach my $key (sort keys %mach_detail) {
        #print "\t$key => $mach_detail{$key}\n";
        printf("\t%${max_len}s => %s\n", $key, $mach_detail{$key});
    }
}

模块List::Util用于获取max功能。现在你得到了

Description: MC-5897
        ---
        machine => 23.73.134.235
        seconds => 20
         status => Failed install
            try => 1
        ---
        machine => 23.73.134.140
        seconds => 20
         status => Failed install
            try => 1

一些相关的近期SO资源:nested hash/arrayarray of hashes