2010-09-03 55 views
1

我將下面的YAML流加載到Perl的數組中,我想遍歷與Field2相關的數組。在Perl中,如何遍歷由YAML加載的散列數組?

use YAML; 

my @arr = Load(<<'...'); 
--- 
Field1: F1 
Field2: 
- {Key: v1, Val: v2} 
- {Key: v3, Val: v4} 
--- 
Field1: F2 
Field2: 
- {Key: v5, Val: v6} 
- {Key: v7, Val: v8} 
... 

foreach (@arr) { 
    @tmp = $_->{'Field2'}; 
    print $#tmp; # why it says 0 when I have 2 elements? 

    # Also why does the below loop not work? 
    foreach ($_->{'Field2'}) { 
    print $_->{'Key'} . " -> " $_->{'Val'} . "\n"; 
} 
} 

我很欣賞任何反饋。謝謝。

回答

6

因爲你沒有正確使用參考。您可能需要重讀perldoc perlreftutperldoc perlref

#!/usr/bin/perl 

use strict; 
use warnings; 

use YAML; 

my @arr = Load(<<'...'); 
--- 
Field1: F1 
Field2: 
- {Key: v1, Val: v2} 
- {Key: v3, Val: v4} 
--- 
Field1: F2 
Field2: 
- {Key: v5, Val: v6} 
- {Key: v7, Val: v8} 
... 

for my $record (@arr) { 
    print "$record->{Field1}:\n"; 
    for my $subrecord (@{$record->{Field2}}) { 
     print "\t$subrecord->{Key} = $subrecord->{Val}\n"; 
    } 
} 
+0

你沒有解決Martin詢問'Field2'鍵的hashref值的部分。 – daxim 2010-09-03 16:13:59

+1

@daxim鏈接解決了與參考相關的問題。 – 2010-09-03 16:59:58

1

您需要使用數據結構和參考進行一些練習。這個作品:

use 5.010; 
use strict; 
use warnings FATAL => 'all'; 

use YAML qw(Load); 

my @structs = Load(<<'...'); 
--- 
Field1: F1 
Field2: 
- {Key: v1, Val: v2} 
- {Key: v3, Val: v4} 
--- 
Field1: F2 
Field2: 
- {Key: v5, Val: v6} 
- {Key: v7, Val: v8} 
... 

# (
#  { 
#   Field1 => 'F1', 
#   Field2 => [ 
#    { 
#     Key => 'v1', 
#     Val => 'v2' 
#    }, 
#    { 
#     Key => 'v3', 
#     Val => 'v4' 
#    } 
#   ] 
#  }, 
#  { 
#   Field1 => 'F2', 
#   Field2 => [ 
#    { 
#     Key => 'v5', 
#     Val => 'v6' 
#    }, 
#    { 
#     Key => 'v7', 
#     Val => 'v8' 
#    } 
#   ] 
#  } 
#) 

foreach (@structs) { 
    my $f2_aref = $_->{'Field2'}; 
    print scalar @{ $f2_aref }; # 2 

    foreach (@{ $f2_aref }) { 
     say sprintf '%s -> %s', $_->{'Key'}, $_->{'Val'}; 
    } 

#  v1 -> v2 
#  v3 -> v4 
#  v5 -> v6 
#  v7 -> v8 
} 
+1

爲什麼使用'sprintf'而不是字符串插值?而且,這段代碼不會運行。你需要使用'feature'編譯指示或者說'use 5.12;'(在這種情況下,你不需要'use strict;')來使用'say'函數。 – 2010-09-03 15:34:58

+0

@Chas。歐文斯:我認爲你的意思是'使用5.012;'sprintf通常使得代碼比內插更清晰。 – ysth 2010-09-03 15:51:00

+0

因爲它是(主觀)更好的風格。有些引用不會插入(很容易,也就是說,我知道ref-deref技巧),[它浪費任何腦力真是愚蠢](http://en.wikipedia.org/wiki/Don't_Make_Me_Think)決定我是否可以使用這些瑣碎的事情,當一個像sprintf這樣的構造,OTOH總是有效的。 - 我添加了'使用5.010;'。現在請刪除您的downvote。 – daxim 2010-09-03 15:56:36