访问存储的数组和散列嵌套层中的数据

问题描述 投票:0回答:2

我有以下数据结构,以数组和散列的组合形式存储数据:

$data = [
          {
            'foo' => {
                       'lang' => 'en',
                       'contact' => [
                                      {
                                        'email' => '[email protected]'
                                      },
                                      {
                                        'phone' => '2125551212'
                                      }
                                    ],
                       'browser' => 'firefox'
                     }
          },
          {
            'bar' => {
                       'lang' => 'fr',
                       'contact' => [
                                      {
                                        'email' => '[email protected]'
                                      },
                                      {
                                        'phone' => '9125551212'
                                      }
                                    ],
                       'browser' => 'lynx'
                     }
          }
        ];

如何获取包含 bar 电子邮件的字符串? 可能存在其他数据,因此无法使用硬编码数组索引访问任何内容。

我使用 grep 的各种组合进行了实验,但由于数据的嵌套方式,并没有取得太大的成功。

arrays perl hash
2个回答
2
投票

首先,严惩创建该结构的人。您的真实数据中可能还有更多内容,但我在现实生活中也看到过这种笨拙的结构。

遍历数据结构得到联系人:

 my $contact = $data->[1]{bar}{contact};

现在有点棘手,因为

$contact
是一个哈希数组,其中只有一个(或可能少于所有)哈希具有您需要的内容。您可以提取具有
email
键的哈希值:

 my @hashes = grep { exists $_->{email} } @$contact;

这就是所有带有

email
键的哈希值。现在提取值:

 my @email = map { $_->{email} } @hashes;

您可以通过各种方式将它们放在一起以摆脱临时值:

 my @email =
      map { $_->{email} }
      grep { exists $_->{email} }
      $data->[1]{bar}{contact}->@*;

如果没有

map
键,我可能会使用
email
返回一个空列表:

 my @email = 
      map { exists $_->{email} ? $_->{email} : () }
      $data->[1]{bar}{contact}->@*; 

这是我在 Intermediate Perl 中介绍的那种东西,但是 Perl Data Structures Cookbook 也不错。


0
投票
no autovivification;
print
  map {
    map { $_->{email} // () }
      @{ $_->{bar}{contact} // [] }
    } @$data;

需要模块自动生成以避免用新元素破坏数据。

如果您需要多次查找,最好将您的数据重组为直接且危险性较小的数据。

© www.soinside.com 2019 - 2024. All rights reserved.