2011-12-27 84 views
2

我在訪問數據時遇到問題,在問題的標題中進行了描述。
數據的結構如下:陣列引用數組散列數組

my @structure = (
    { 
    "Name" => "Test", 
    "Param1" => 1, 
    "Data1" => \@test1, 
    "Data2" => [\@test3], 
    "Data3" => [\@test1, \@test2],  
    }, 
    ... 
); 

,我需要訪問陣列@test3的第一(#0)的元素。
我想是這樣的:

my @array = @{$_->{'Data2'}}[0]; 
print $array[0]; 

但後來我到了陣列(ARRAY(0x239c3c))的參考,而不是需要的意思。我覺得這裏有一些我不瞭解的全球性問題。
難道你不能解釋爲什麼我應該解決所需的意義?
非常感謝。

回答

3

您可以使用->的語法糖來獲得您想要的參考。它比使用圓括號更清潔。

,我需要訪問的第一個(#0)數組的元素@ TEST3

好吧,在你的結構,這將會是:

my $element = $structure[0]->{Data2}->[0]->[0]; 

這相當於,但更難讀:

my $element = ${${${$structure[0]}{Data2}}[0]}[0]; 

而且,在這種特殊情況下,您可以消除語法糖->

my $element = $structure[0]{Data2}[0][0]; 

不過,我不知道這是否使得它更易於閱讀,並且存在解析的默認方式可能不會做的正是你想要的東西的情況。我傾向於擠壓一切融合在一起時,我指的是一個數組的數組,但僅此而已:

my $element = $array[0][3];  #This is okay 
my $element = $array[0]->[3]; #Same as above, but with -> syntax 

否則,我將使用的->句法甜味劑。

下面是語法的解釋:

  • $structure[0]是您@structure數組的第一個項目的引用。這包含對散列的引用。
  • $structure[0]->{Data2}是對@structure陣列中第一項中散列元素Data2的引用。這是對數組的引用。
  • $structure[0]->{Data2}->[0]是對@structure數組的第一個元素(0)中的Data2散列元素中第一個數組引用的引用。這是你的@test3陣列。
  • $structure[0]->{Data2}->[0]->[0]@test3數組的第一個元素。

我還建議您在編寫代碼時使用Data::Dumper模塊。它可以幫助您瞭解您參考的結構並幫助指出關卡中的任何錯誤。例如:

use Data::Dumper; 

print $structure[0]->{Data2}->[0] . "\n"; 

會告訴你這是對另一個數組層的引用。

print "$structure[0]\n"; 

會告訴你這是一個散列引用,其中每個項目包含對數組數組的引用。


無論何時您使用這些高度複雜的結構,它都會尖叫使用面向對象的Perl編碼。我不是100%確定你在做什麼,所以我無法幫助你處理你的物體,但是高度複雜的結構往往會破裂,幾乎不可能維持。

例如,我們現在這樣做:

use strict; 
use warnings; 

my $Foo = "bar"; 
print "Foo = $foo\n"; 

這可以迅速檢測到我做$foo代替$Foo拼錯我的變量名。與老版本的Perl相比,這是一個很大的改進,在這種類型的錯誤檢查無法完成。

不過,現在看這個:

use strict; 
use warnings; 

my %hash; 
$hash{Foo} = "bar"; 
print "Foo = $hash{foo}\n"; 

我們已經失去了編譯錯誤檢查。 %hash是一個合法變量,但定義了$hash{Foo}而不是$hash{foo}。在這種情況下,use strict對你沒有任何幫助。面向Perl的

使用對象返回該錯誤檢查:

use strict; 
use warnings; 
use Object::Foo; 

my $hash = Object::Foo->new; 
$hash->Foo(bar); 
print "Foo = " . $hash->foo . "\n"; 

哎呦!該方法應該是Foo而不是foo。但是,Perl能夠檢測到方法foo不存在,並且會再次在編譯時產生錯誤。

在上面的例子中,它非常直截了當,但是你正在處理數組數組的散列數組。每個參考訪問錯誤的可能性乘以100。而且,由於您必須在代碼中反覆說明這些引用,因此可能會在數十個不同的地方找到錯誤。即使您最初可以編寫代碼,然後在代碼中對整個結構進行註釋,但在三個月後再次回到本代碼時,仍然無法保持這一點。

看一看Perldoc's Tutorials,並通過面向對象編程。

+0

非常感謝您的時間和建議!使用這樣複雜的結構對我來說是個例外,我覺得OOP還爲時過早。但我一定會在將來研究它。 – evgeny9 2011-12-29 16:58:23

4

print $structure[0]{'Data2'}[0][0];將工作!

你只是忘記了最後一關!

$_->{'Data2'}是對匿名數組的引用。

@{$_->{'Data2'}}[0]爲您提供了匿名數組的第一個元素,即對另一個數組的引用!如果你有"Data2" => \@test3,而不是"Data2" => [\@test3],

+0

感謝您的簡短實際答案 - 它的工作。 – evgeny9 2011-12-29 17:00:09

4
use strict; 
use warnings; 

my @test1 = (1,2,3); 
my @test2 = (4,5,6); 
my @test3 = (7,8,9); 

my @structure = (
    { 
    "Name" => "Test", 
    "Param1" => 1, 
    "Data1" => \@test1, 
    "Data2" => [\@test3], 
    "Data3" => [\@test1, \@test2], 
    } 
); 

print $structure[0] # $structure is an array, you want first element... 
    ->{'Data2'}  # ...which is a hash reference, you want value for 'Data2'... 
    ->[0]    # ...which is holding an array reference to (one element) array @test3... 
    ->[0];   # ...which is an array reference, and you want first element 

打印7

您的代碼會工作。

+0

謝謝 - 您的工作示例確實幫助我消除了錯誤(最初,結構太複雜)。 – evgeny9 2011-12-29 17:02:12