2013-10-30 44 views
0

another thread中,給出了一個具體示例如何訪問特定的密鑰。 無論如何,編碼一個可以訪問任意密鑰的子節點時是否有最佳實踐?例如,sub get_lat將是一個具體的屬性 - 緯度。但關注更普遍的選項,如sub get_value_by_keys($$$)&get_value_by_keys(bounds,northeast,lat)將返回51.4770228如何使用帶有通用潛艇的Perl結構?

address_components => [ 
    { 
     long_name => "Blackheath Avenue", 
     short_name => "Blackheath Ave", 
     types => ["route"], 
    }, 
    { 
     long_name => "Greater London", 
     short_name => "Gt Lon", 
     types => ["administrative_area_level_2", "political"], 
    }, 
    { 
     long_name => "United Kingdom", 
     short_name => "GB", 
     types => ["country", "political"], 
    }, 
    { 
     long_name => "SE10 8XJ", 
     short_name => "SE10 8XJ", 
     types => ["postal_code"], 
    }, 
    { 
     long_name => "London", short_name => "London", types => ["postal_town"] 
    }, 
    ], 

    formatted_address => "Blackheath Avenue, London SE10 8XJ, UK", 
    geometry => { 
    bounds  => { 
     northeast => { lat => 51.4770228, lng => 0.0005404 }, 
     southwest => { lat => 51.4762273, lng => -0.0001147 }, 
    }, 
    location  => { lat => 51.4766277, lng => 0.0002212 }, 
    location_type => "APPROXIMATE", 
    viewport  => { 
     northeast => { lat => 51.4779740302915, lng => 0.00156183029150203 }, 
     southwest => { lat => 51.4752760697085, lng => -0.00113613029150203 }, 
    }, 
    }, 

    types => ["route"], 

} 

任何提示如何解決這個問題,以及如何應對這樣的結構?

+2

你的數據結構有一個多餘的大括號,並且不是有效的Perl。請張貼將編譯的東西。 – Borodin

+0

這是從舊系統日誌輸出的數據轉儲,也就是Data :: Dumper的返回值,據我所知關於由地理編碼器返回的位置。這不應該編譯,因爲它不是一個代碼。 – mnemonic

+0

'Data :: Dumper'生成有效的,可編譯的Perl代碼。但是您發佈的示例已被截斷,因此它不再有效。請張貼全部。 – Borodin

回答

3

要下降到數據結構的任意級別,請從頂部開始。使用變量來保存對當前級別的引用,並在每次找到下一級別時更新它。如果你把它所有的方式來結束,這就是你想要的值:

sub get_value_by_keys { 
    my($current_level, @keys) = @_; 

    foreach my $key (@keys) { 
     if(eval{ exists $current_level->{$key} }) { 
      print "$key key exists\n"; 
      $current_level = $current_level->{$key}; # the trick 
      } 
     else { return } 
     } 

    return $current_level; 
    } 

然後,數據結構,並要鍵調用它:

get_value_by_keys($data, qw(geometry bounds northeast lat)); 

你不需要原型。

+0

這真的很棒 – mnemonic

0

有幾個CPAN模塊正在做你想做的。例如Data::Diver

use Data::Diver qw(Dive); 
print Dive($data, qw(geometry bounds northeast lat)), "\n"; 

該模塊的優點是,它也可以處理該數據結構內的陣列的引用。例如,爲了獲得第二地址組件使用的LONG_NAME:

print Dive($data, qw(address_components 1 long_name)), "\n"; 

其它模塊實現XPath的類似的語法(Data::DPathData::Path),在這裏你會使用像"//geometry/bounds/northeast/lat"一個字符串來訪問值。

+0

對不起 - 已經實施了其他版本工作正常。你的答案將被測試/使用也許是另一次。但非常感謝。 – mnemonic