我有一个使用 fethro_hashref() 从数据库构建的 hashref 数组。数据结构的构建如下:
while (my $ref = $sth->fetchrow_hashref()) {
push @lines, $ref;
}
我按程序名称升序对查询中的数据进行排序,因此数组中的所有引用仍按字母顺序排列。然后,我遍历每个哈希并找到数值上等于 '1'
的值。然后,我获取 caolumn 名称,并将其存储起来,以便与具有该程序名称的其余哈希引用进行比较,以确保它们在同一列中都具有 '1'
。
my $pgm = "";
my $met_lvl = "";
my @devs = ();
my %errors = ();
my $error = "";
foreach my $line_ref (@lines) {
if ($pgm ne $line_ref->{"PROGRAM"}) {
if (@devs && $error) {
# print " Different number metal layers for $pgm: @devs \n";
$error = "";
}
@devs = ();
$pgm = $line_ref->{"PROGRAM"};
($met_lvl) = grep { $line_ref->{$_} == 1 } keys(%$line_ref);
push @devs, $line_ref->{"DEVICE"};
} elsif ($pgm eq $line_ref->{"PROGRAM"}) {
push @devs, $line_ref->{"DEVICE"};
my ($met_chk ) = grep { $line_ref->{$_} == 1 } keys(%$line_ref);
if ($met_chk ne $met_lvl) {
$errors{$line_ref->{"PROGRAM"}} = $line_ref->{"PROGRAM"};
$error = "YUP";
}
}
}
我希望能够根据数据库中匹配的列名称单独访问哈希引用。如何访问具有“PROGRAM”键的“TEST”值的哈希引用?我使用 Data::Dumper 提供了一些我想根据“PROGRAM”值访问的 hashref 的示例:
'PLM' => undef,
'SLM' => undef,
'QLM' => undef,
'DEVICE' => 'DEV1',
'TLM' => '1',
'DLM' => undef,
'ROUTING' => 'NORMAL',
'PROGRAM' => 'TEST'
};
$VAR455 = {
'PLM' => undef,
'SLM' => undef,
'QLM' => undef,
'DEVICE' => 'DEV2',
'TLM' => '1',
'DLM' => undef,
'ROUTING' => 'NORMAL',
'PROGRAM' => 'TEST'
};
$VAR456 = {
'PLM' => undef,
'SLM' => undef,
'QLM' => undef,
'DEVICE' => 'DEV3',
'TLM' => '1',
'DLM' => undef,
'ROUTING' => 'NON_STANDARD',
'PROGRAM' => 'EXP'
};
$VAR457 = {
'PLM' => undef,
'SLM' => undef,
'QLM' => undef,
'DEVICE' => 'DEV4',
'TLM' => '1',
'DLM' => undef,
'ROUTING' => 'NORMAL',
'PROGRAM' => 'FINAL'
};
我希望能够访问包含相同程序名称的哈希引用的键值。我什至无法开始弄清楚要使用什么类型的操作来实现此目的。我认为 map
是正确的方法,但是取消引用数组中每个元素(hashref)的“PROGAM”值超出了我的理解范围。我希望我能够很好地定义问题,以便能够为你们提供帮助。
编辑:想要访问具有相同“程序”值的哈希引用的动力是能够提供所选值的输出以打印到日志文件。因此,在我比较并找到具有相同“程序”值的哈希引用之间的差异之后“PROGRAM”值,我想再次访问它们,并将所需的列值打印到lofgile。
最佳答案
看起来您需要提取具有相同 PROGRAM
名称的数据子集(哈希引用)。
可以预处理数据以构建一个散列,其中这些名称作为键,数组引用(具有合适的散列引用)作为值。然后一次处理一个组。
use warnings;
use strict;
use feature 'say';
use Data::Dumper; # to print complex data below
... populate @lines with hashrefs as in the question or copy-paste a sample
# Build hash: ( TEST => [ hashrefs w/ TEST ], EXP => [ hashrefs w/ EXP ], ... )
my %prog_subset;
for my $hr (@lines) {
push @{ $prog_subset{$hr->{PROGRAM}} }, $hr;
# Or, using "postfix dereferencing" (stable from v5.24)
# push $prog_subset{$hr->{PROGRAM}}->@*, $hr;
}
foreach my $prog (keys %prog_subset) {
say "\nProcess hashrefs with PROGRAM being $prog";
foreach my $hr (@{ $prog_subset{$prog} }) {
say Dumper $hr;
}
}
(参见 postfix dereference )
现在 %prog_subset
包含键 TEST
、EXP
、FINAL
(以及其他任何 PROGRAM
名称在数据中),每个值都有一个包含具有该 PROGRAM
名称的所有 hashref 的 arrayref。
还有其他方法,并且有可以利用的库,但这应该可以做到。
关于perl - 哈希引用数组 : How to access based on hashref "column" values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74879710/