2016-03-03 53 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