Perl,遍历哈希数组并根据条件打印特定的哈希元素

Perl, loop through array of hashes and print a specific hash element based on criteria

我有一个更大的多维哈希,它由哈希和其中的数组组成,我能够从仅对整个较大哈希有用的哈希数组中获取哈希数组,现在我正在尝试打印键的特定元素或值。

原始哈希

{
      "grade1": {
        "sections": {
          "groups": "group-a"
        }
      },
      "grade2": {
        "sections": {
          "groups": "group-b"
        }
      },
      "grade3": {
        "departments": [
          {
            "allowedsubjects": "\ngeneral\nmath\nphysics\nchemistry",
            "name": "class1",
            "multiple": false,
            "description": "",
            "required": "optional"
          },
          {
            "allowedsubjects": "\ngeneral\nbiology\nphysics\nchemistry",
            "name": "class2",
            "multiple": false,
            "description": "",
            "required": "optional"
          }
        ]
      }
    }

我的脚本

#!/usr/bin/perl
use Cpanel::JSON::XS;
use strict;
use v5.16.3;
use Data::Dumper;

my $json_text ='{ "grade1": { "sections": { "groups": "group-a" } }, "grade2": { "sections": { "groups": "group-b" } }, "grade3": { "departments": [ { "allowedsubjects": "\ngeneral\nmath\nphysics\nchemistry", "name": "class2", "multiple": false, "description": "", "required": "optional" }, { "allowedsubjects": "\ngeneral\nbiology\nphysics\nchemistry", "name": "class1", "multiple": false, "description": "", "required": "optional" } ] } }';

my $json_obj = decode_json($json_text);

#print Dumper $json_obj;
my %school = %{$json_obj};
## Half working
    my @AoH = @{$school{"grade3"}{"departments"}};
    my @lines;
    for my $href ( @AoH ) {
        for my $key ( keys %$href ) {
          push @lines, $href->{$key};
         }
    }
print @lines;

输出

0optionalclass2
general
math
physics
chemistryoptionalclass1
general
biology
physics
chemistry0

如何根据 class1 或 class2 作为条件仅打印 allowedsubjects 的值。

如果选择 class1,预期输出

general
math
physics
chemistry

让我们从避免不必要的散列和数组副本开始。我们还将使用比 AoHhrefkey.

更好的变量名
my $school = decode_json($json);
my $depts = $school->{grade3}{departments};

现在我们想要名称值为 $dept_name 的部门。 grep 是个很好的过滤工具。

my $dept_name = 'class1';
my @matching_depts = grep { $_->{name} eq $dept_name } @$depts;

然后,这只是迭代匹配部门并打印所需值的问题。

for my $dept (@matching_depts) {
   say $dept->{allowedsubjects};
}

除了不完全是。打印

                 <-- Blank line
general
biology
physics
chemistry

修复:

for my $dept (@matching_depts) {
   say substr($dept->{allowedsubjects}, 1);
}

替代修复:

for my $dept (@matching_depts) {
   my @subjects = grep { $_ ne "" } split /\n/, $dept->{allowedsubjects};
   for my $subject (@subjects) {
      say $subject;
   }
}

您可以大大简化代码。归结为这个循环。

for my $department ( @{ $school->{grade3}{departments} } ) {
    if ($department->{name} eq 'class1') {
        print $department->{allowedsubjects};
    }
}

我已删除您的 @lines,因为不需要存储此示例的输出。我还删除了 @AoH,因为我们可以直接访问它。我已将 $href 重命名为 $department,这更具描述性。

然后归结为查看每个部门内部的特定name键,与您想要的class进行比较,然后直接打印allowedsubjects