访问解码为 HASH 和哈希引用数组的 JSON

Dou*_*las 2 perl hash json data-structures perl-data-structures

鉴于以下转储程序输出,有没有办法遍历每个散列以仅列出每个results->id记录下的项目?我希望能够说这样的话:

print $results{1342}{'domain'};

并让语句返回testing11.com结果。

我是否必须首先通读所有results数组,然后使用它$results[$counter]{id}来访问那里的数据?我不知道如何继续。

$VAR1 = { 
          'end_time' => 1466017739,
          'options' => {
                         'hour_offset' => '00',
                         'timezone' => 'America/New_York'
                       },
          'field_headers' => {
                              'priority' => 'Priority',
                              'status' => 'Status',
                              'assignee_external_id' => 'Assignee external id',
                              'initially_assigned_at' => 'Initially assigned at'
                             },
          'results' => [
                         {
                           'priority' => 'High',
                           'status' => 'Open',
                           'domain' => 'testing11.com',
                           'generated_timestamp' => 1546547669,
                           'id' => 1342
                          },
                         {
                           'priority' => 'Low',
                           'status' => 'Open',
                           'domain' => 'testing22.com',
                           'generated_timestamp' => 1464567669,
                           'id' => 7062
                          },
                         {
                           'priority' => 'Low',
                           'status' => 'Closed',
                           'domain' => 'testing33.com',
                           'generated_timestamp' => 1464267669,
                           'id' => 432
                          }]
      }
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 5

您的转储显示了一个 hashref,其中包含一个标量、两个 hashref 和一个 arrayref。arrayref 具有元素的 hashrefs。如果要从中检索特定元素,则需要知道索引。

$top_level->{results}->[0]->{domain};  # is 'testing11.com'
$top_level->{results}->[0]->{status};  # is 'open'
Run Code Online (Sandbox Code Playgroud)

遍历它取消对数组的引用

foreach my $result (@{ $top_level->{results} }) {
    print "$result->{id}\n";
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以从results特定键的所有元素中获取值,例如 forid

my @ids = map { $_->{id} } @{ $top_level->{results} };
say "@ids";
Run Code Online (Sandbox Code Playgroud)

印刷

1342 7062 432

请注意,对于包含引用的嵌套结构,您还可以使用语法

$top_level->{results}[0]{domain};  # is 'testing11.com'  
Run Code Online (Sandbox Code Playgroud)

->下标之间的是可选的,请参阅在 perlref使用引用中的规则 3 。

当哈希键是字符串时,它们应该被引用

$top_level->{'results'}[0]{'domain'};
Run Code Online (Sandbox Code Playgroud)

但是,语法快捷方式允许我们省略裸词上的引号。但是如果里面有除裸字以外的任何东西{},它将被解释为一个表达式并求值。因此,如果有任何疑问,请使用引号。您希望始终保持一致的符号。

资源:教程perlreftut、参考perlref和数据结构说明书perldsc


stevieb的回答中给出了一个直接的解决方案,创建了一个反向查找。复制到这里供参考

my $results = $VAR1->{results};

my %by_ip = map {$_->{id} => $_} @$results;

print "$by_ip{1342}->{domain}\n";
Run Code Online (Sandbox Code Playgroud)