You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于哈希引用的列值访问哈希引用数组?

问题描述

我通过fetchrow_hashref()从数据库构建了一个哈希引用数组,数据结构构建代码如下:

while (my $ref = $sth->fetchrow_hashref()) {
    push @lines, $ref;
}

数据已按program name升序排序,数组中的引用保持字母顺序。随后我遍历每个哈希,找到值等于'1'的键,获取列名并存储,用来对比同program name的其他哈希引用是否在同一列都有'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"的哈希引用?以下是示例哈希引用:

{
    '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'
};

我需要访问具有相同program name的哈希引用的键值,推测可以用map,但不清楚如何解引用数组中每个哈希引用的"PROGRAM"值。补充说明:访问同PROGRAM值的哈希引用,是为了将选定值输出到日志文件,在对比发现差异后,再次访问它们并打印所需列值到日志。

解决方案

方法1:用grep直接筛选目标哈希引用

直接通过grep遍历数组,筛选出PROGRAM值匹配的哈希引用:

# 获取所有PROGRAM为"TEST"的哈希引用
my @test_programs = grep { $_->{"PROGRAM"} eq "TEST" } @lines;

# 遍历输出这些哈希的DEVICE和ROUTING值到日志
foreach my $ref (@test_programs) {
    print LOG "PROGRAM: $ref->{PROGRAM}, DEVICE: $ref->{DEVICE}, ROUTING: $ref->{ROUTING}\n";
}

方法2:提前构建分组哈希(高效复用)

如果需要多次按PROGRAM分组访问数据,建议先把数组转换成以PROGRAM为键的哈希,值是对应哈希引用的数组,后续访问会更高效:

# 构建分组哈希
my %program_groups;
foreach my $ref (@lines) {
    my $pgm_name = $ref->{"PROGRAM"};
    push @{$program_groups{$pgm_name}}, $ref;
}

# 访问PROGRAM为"TEST"的所有哈希引用
my @test_refs = @{$program_groups{"TEST"}};

# 输出到日志
foreach my $ref (@test_refs) {
    print LOG "DEVICE: $ref->{DEVICE}, TLM: $ref->{TLM}\n";
}

# 针对之前检测到的错误PROGRAM,直接输出对应数据
foreach my $err_pgm (keys %errors) {
    my @err_refs = @{$program_groups{$err_pgm}};
    print LOG "ERROR - PROGRAM $err_pgm has inconsistent metal layers:\n";
    foreach my $ref (@err_refs) {
        my ($met_col) = grep { $ref->{$_} eq '1' } keys %$ref;
        print LOG "  DEVICE: $ref->{DEVICE}, Metal Layer: $met_col\n";
    }
}

map的使用示例

如果想用map提取特定字段,比如获取所有"TEST" PROGRAM对应的DEVICE列表:

my @test_devices = map { $_->{"PROGRAM"} eq "TEST" ? $_->{"DEVICE"} : () } @lines;
# 输出结果:('DEV1', 'DEV2')

内容的提问来源于stack exchange,提问作者WetCheerios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:15:29