2016-03-03 77 views
1
#!/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. 

我要循环,并得到他们的价值观。 我不想使用自卸车方法来获取值,我想通过循环方法来获取这些值。任何帮助,将不胜感激。谢谢通过所有的键值对非关联嵌套的哈希在Perl

我这样做是为了解决这个问题并获取'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"; 
    } 
} 
+0

'$ hashref2 {$ machineresult}'是对数组的引用,所以'keys%{$ hashref2 {$ machineresult}}'是没有意义的。你希望'@ {$ hashref2 {$ machineresult}}' – ikegami

+0

它对我来说看起来你的'%ani_hash'总是有2个元素,'machine_results'和'description',而你只想遍历数组'machine_results',对吧? – PerlDuck

+0

@DavidO:我有一个问题,你的讽刺,以及暗示,*递归*是处理这种结构的唯一方法 – Borodin

回答

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用于获取一个新的“以子”复制%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

+0

谢谢@zdim的参考和代码:)。一定会查找它。 – hitman99

+0

@ hitman99最受欢迎。在您从全面的资源中彻底阅读之前,对这些东西的很好的参考是非常宝贵的。幸运的是,SO有很多很好的,亲自动手的,点对点的介绍。完成我的编辑,这样就可以很好地打印整个结构。我希望这对你有用。 – zdim

+0

这当然有帮助。我同意你关于SO的观点。谢谢:) – hitman99

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}是你的机器的结果数组引用。
  • @{ $hashref->{machine_results} }解引用它到一个数组,你可以遍历,所以
  • $result是这些数组项这又是一个哈希
  • %{$result}它被解除引用一个散列的引用之一,我们遍历(排序)键

这当然,假设你的数据结构是在,它是,即machine_results持有一个arrayref与哈希里面里面。

+0

谢谢@Perl狗的帮助。我修改了代码并编辑了帖子。让我知道它看起来不错。 – hitman99