perl - 哈希引用数组 : How to access based on hashref "column" values

标签 perl dbi hashref

我有一个使用 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 包含键 TESTEXPFINAL (以及其他任何 PROGRAM 名称在数据中),每个值都有一个包含具有该 PROGRAM 名称的所有 hashref 的 arrayref。

还有其他方法,并且有可以利用的库,但这应该可以做到。

关于perl - 哈希引用数组 : How to access based on hashref "column" values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74879710/

相关文章:

arrays - perl 组使用 fetchrow_hashref 生成散列

perl - 在Perl中,创建与程序包同名的子例程是否有害?

performance - DBI 语句句柄可以使用缓存调用来执行()吗?

perl - 使用Perl的DBI,如何连接fetchrow_arrayref的结果?

perl - 为什么我不能从 Perl 连接到 postgres?

perl - 在 Perl 中 fork 多个子节点并使用管道进行双向通信

Perl - $?在 Windows 2008 64 位上,-1 返回代码显示 0

perl - 有了SQL SELECT查询,如何获得项目数?

arrays - 合并 Perl Hashref 和 unique