Perl嵌套散列匹配和合并



我有一个被读取并分割成%对象的文件,这些%对象的填充如下所示。

$VAR1 = 'cars';
$VAR2 = {
'car1' => {
'info1' => '"fast"',
'info2' => 'boring'
},
'car2' => {
'info1' => '"slow"',
'info2' => 'boring info'
},
'car3' => {
'info1' => '"unique"',
'info2' => 'useless info'
}
};
$VAR3 = 'age';
$VAR4 = {
'new' => {
'info3' => 'rust',
'info4' => '"car1"'
},
'old' => {
'info3' => 'shiny',
'info4' => '"car2" "car3"'
}
}
};              

我的目标是插入像"car1快生锈,car2慢闪亮,car3独特闪亮"这样的数据;在数据库中,但我不能得到例如rust匹配基于info4的年龄;. .

my $key = cars;
my $key2 = age;
foreach my $obj (keys %{$objects{$key}}) {                          # for every car
@info1s = $objects{$type}{$obj}{'info1'} =~ m/"(.*?)"/g;        # added to clean up all info1
foreach my $infos ($info1s) {
dbh execute insert $obj $infos                              # this gives me "car1 fast, car2 slow, car3 unique"
} 
...

谁能告诉我正确的方向来获取和存储info4与相关的info1/info2?

谢谢!

我的目标如下:在最深层的hashref中获取$VAR4中(info4)键的值,并在$VAR2hashref中找到它们作为顶级键。然后将(info3)键中的一个值与它们关联,即它们的"兄弟"键。在他们自己的$VAR4的最深层的哈希ref中,以及$VAR2中的键(info1)的值。

出于这个目的,可以手动遍历结构,特别是如果它总是具有相同的两层,但使用库更容易、更好。我使用Data::Leaf::Walker来获取叶子(最深的值)和键路径,使用Data::Diver来获取已知路径的值。
use warnings;
use strict;
use feature 'say';
use Data::Dump;    
use Data::Leaf::Walker;
use Data::Diver qw(Dive);
my $hr1 = {
'car1' => { 'info1' => 'fast',   'info2' => 'boring' },
'car2' => { 'info1' => 'slow',   'info2' => 'boring info' },
'car3' => { 'info1' => 'unique', 'info2' => 'useless info' }
};
my $hr2 = {
'new' => { 'info3' => 'rust',  'info4' => 'car1' },
'old' => { 'info3' => 'shiny', 'info4' => 'car2 car3' }
};
my $walker = Data::Leaf::Walker->new($hr2);    
my %res;    
while ( my ($path, $value) = $walker->each ) { 
next if $path->[-1] ne 'info4';
# Some "values" have multiple needed values separated by space
for my $val (split ' ', $value) { 
# Get from 'info4' path the one to its sibling, 'info3'
my @sibling_path = ( @{$path}[0..$#$path-1], 'info3' );
# Collect results: values of `info3` and `info1`
push @{$res{$val}}, 
Dive( $hr2, @sibling_path   ), 
Dive( $hr1, ($val, 'info1') );
}
}
dd %res;

为了简单起见,这里假设了一些东西并采取了一些捷径。

首先,我使用问题中的显式infoN键和两层结构。如果数据是不同的,或者可以是不同的,这应该不难调整。

接下来,假设像car1这样的值总是作为键存在于另一个hashref中。如果该键可能不存在,则为该键添加exists检查

我已经从数据中删除了一些额外的引号。(如果这是用于数据库条目,则在构造语句时执行此操作。如果数据带有这些额外的引号,那么应该很容易调整代码以考虑它们。

以上程序打印

{Car1 => ["rust", "fast"],Car2 =>["闪亮","缓慢"],Car3 =>["闪亮","独特"],}

(我使用Data::Dump来显示复杂的数据结构,因为它的简单性和默认的紧凑输出。)

最新更新