[英]Perl nested data structures
我在將大腦包裹在返回的數據結構上時遇到麻煩...我需要做的是檢查結果,如果是HASH則修改字段。 在“結果”中,需要將任何具有KEY為“ null”且值為“ 1”的HASH的KEY更改為“ 0”。 下面,我從返回的Data :: Dumper粘貼了一些示例數據。 在這種情況下,我想在四個不同的地方更改數據。 我已經處理了一段時間了,只是想不通..任何幫助表示贊賞。
$VAR1 = {
'results' => [
{
'admin' => 'DUMMY DATA',
'object' => 'DUMMY DATA',
'ifDescr' => 'DUMMY DATA',
'total_device' => {
'null' => '1'
},
'ifIndex' => 'DUMMY DATA',
'oper' => 'DUMMY DATA',
'percent_online' => 'DUMMY DATA',
'device_offline' => {
'null' => '1'
},
'dataflow' => 'DUMMY DATA',
'Map' => 'DUMMY DATA',
'ifdevice' => 'DUMMY DATA',
'device_online' => 'DUMMY DATA'
},
{
'admin' => 'DUMMY DATA',
'object' => 'DUMMY DATA',
'ifDescr' => 'DUMMY DATA',
'total_device' => {
'null' => '1'
},
'ifIndex' => 'DUMMY DATA',
'oper' => 'DUMMY DATA',
'percent_online' => 'DUMMY DATA',
'device_offline' => {
'null' => '1'
},
'dataflow' => 'DUMMY DATA',
'Map' => 'DUMMY DATA',
'ifdevice' => 'DUMMY DATA',
'device_online' => 'DUMMY DATA'
}
]
};
我在將大腦包裹在要返回的數據結構上時遇到麻煩...
您已經接受了答案,我只是要澄清對Data::Dumper
輸出的解釋:
{...}
表示對哈希的引用 。 您將看到key => value,
作為哈希元素。 [...]
代表對數組的引用 。 您將看到value,
作為數組元素。 分解您擁有的東西:
$VAR = $VAR1 = {
'results' => [
.... # This is an array reference
]
或$ VAR-> {results} = [];
這是具有單個results
鍵的哈希。 哈希值是對數組的引用。 至今:
$VAR1 = {
'results' => [ # This is the [0] element in my array
{
... # This is a hash reference
}
]
[ # This is the [1] element in my array
{
... # This is a hash reference
}
在此數組中,有兩個值,每個值都指向一個哈希引用:
$VAR->{results}->[0] = {};
$VAR->{results}->[1] = {};
在每個這些數組中,哈希引用都有12個鍵和值:
前10個只是鍵/值對。 最后兩個是對具有單個鍵/值對的其他哈希的引用。 鍵為空。 我認為這是某種錯誤。
現在,我可以像這樣引用其中一項:
$VAR->{results}->[1]->{ifIndex} = 'DUMMY DATA';
假設當前結構,以下是在循環中引用它的方法:
my $VAR = some_function() # Returns a reference to a hash.
for my $result ( keys %{ $VAR } ) { # Dereference the hash reference...
say "Key for results is '$result'"; # Only one result. And that's 'result'...
my @array = $VAR->{$result}; # Dereference the array reference that hash points to
for my $element ( 0..$#array ) { # Now we get to the two elements in the array
say qq(Looking at element #$element);
my $hash_key = $array[$element]; # he hash reference that the array points to
my %inner_hash = %{ $hash_key }; # Another dereference...
for my $key ( keys %inner_hash" ) {
say "\$VAR->{$result}->[$element]->{%hash_key} = "
. $VAR->{$result}->[$element]->{%hash_key};
}
}
}
這不會完全起作用,因為total_device
和device_offline
再次是哈希引用。 我應該在我的最內層循環中例外,並且如果其中任何一個是我的內在散列的關鍵,我都需要進行另一次取消引用才能到達散列。 我會讓你解決。
當然,我知道我的結構,因此我可以編寫一個程序結構來處理它。 如果我不知道數據結構的布局,則必須使用ref
命令來確定我是在引用哈希還是數組,並相應地取消引用和循環。 這幾乎就是Data::Dumper
所做的。
我通常認為這樣的復雜結構來自類構造函數,並且我希望在這樣的Data :: Dumper轉儲中看到對象的受祝福的類名。 在這種情況下,我會告訴您使用該類的方法,而不要解構數據結構並自行修改。 在面向對象的設計中這是不行的。
您應該始終將數據結構視為黑匣子。 您不應該僅僅因為Perl沒有提供盲目性來將結構和方法標記為私有而在窗口中達到頂峰。 舉止仍然很糟糕。
但是,Data :: Dumper沒有顯示類的名稱,因此它不是類對象。 忘掉數據結構。
查看《 Perl參考指南》,以了解是否有助於您解決這種情況。
我並沒有完全理解“散列的任何鍵”的含義-可能是您的意思:“散列的任何值”。 無論如何,如果我做對了,也許這個腳本可能會有所幫助。 它將遞歸檢查數據結構中的哈希並根據需要更改值。
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
# test data given in the post
my $VAR1 = {...}; # truncated
sub recursive_change {
my $hash = shift;
foreach my $key (keys %{$hash}) {
my $value = $hash->{$key};
if ($key eq 'null' && $value eq '1') { # or 1, depends
$hash->{$key} = '0'; # or 0, depends
}
elsif (ref($value) eq 'HASH') {
recursive_change($value);
}
}
}
foreach my $elem (@{$VAR1->{results}}) {
recursive_change($elem);
}
print Data::Dumper->new([ $VAR1 ],[ '*VAR1' ])->Sortkeys(1)->Dump();
編輯:將整個哈希設置為0:
sub recursive_change {
my $hash = shift;
foreach my $key (keys %{$hash}) {
my $value = $hash->{$key};
if (ref($value) eq 'HASH') {
if ($value->{null} eq '1') {
$hash->{$key} = 0;
}
else {
change($value);
}
}
}
}
雖然不是最好的解決方案,但它可以工作。
聽起來您需要遍歷結果的元素,對於每個元素,如果任何值都是hashref,並且該hashref具有鍵值對null => 1,則將其替換為null => 0。
看起來應該像這樣:
# iterate through results
for my $result (@$results) {
# check each hash in results for nested hashes
for my $key (keys(%$result)) {
# if the value here is a hashref, do stuff
if(ref $result->{$key} eq 'HASH') {
# the stuff to be done
# specifically, replace null => 1 with null => 0
$result->{$key}->{null} = 0 if $result->{$key}->{null} == 1;
}
}
}
當我測試它時,它似乎可以滿足您的要求(用null => 0替換4個null => 1實例)。 我敢肯定有一種寫得更好的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.