我无法将大脑包裹在正在返回的数据结构中...我需要做的是检查结果,如果是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'
}
]
};
答案 0 :(得分:1)
我无法将大脑缠绕在正在返回的数据结构中......
您已经接受了答案,我只想澄清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个只是键/值对。最后两个是对具有单个键/值对的另一个散列的引用。键是null。我认为这是某种错误。
现在我可以参考其中一个这样的项目:
$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
所做的。
我通常认为这样一个复杂的结构来自 class 构造函数,我希望在这样的Data ::中看到对象的 blessed 类名。翻斗车转储。在这种情况下,我会告诉你使用该类的方法,而不是解构数据结构并自己进行。这是面向对象设计中的禁忌。
您应始终将数据结构视为黑盒子。你不应该仅仅因为Perl没有提供 blinds 来将结构和方法标记为 private 而达到峰值。这仍然是不礼貌的举止。
但是,Data :: Dumper没有显示类的名称,因此它不是类对象。 Ogle远离数据结构。
查看Perl Reference Tutorial,了解这是否有助于澄清情况。
答案 1 :(得分:0)
我并没有完全明白你的意思"任何关键是HASH" - 可能你的意思是:"任何值为HASH"的值。 无论如何,如果我做对了,也许这个脚本可能会有所帮助。 它将递归检查数据结构内的哈希值,并根据需要更改值。
#!/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);
}
}
}
}
虽然不是最好的解决方案,但它确实有效。
答案 2 :(得分:0)
听起来你需要遍历结果的元素,并且对于每个元素,如果任何值是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的实例)。我确信这是一个更漂亮的方式来写这个。