我有以下数据结构,以数组和散列的组合形式存储数据:
$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 的各种组合进行了实验,但由于数据的嵌套方式,并没有取得太大的成功。
首先,严惩创建该结构的人。您的真实数据中可能还有更多内容,但我在现实生活中也看到过这种笨拙的结构。
遍历数据结构得到联系人:
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 也不错。
no autovivification;
print
map {
map { $_->{email} // () }
@{ $_->{bar}{contact} // [] }
} @$data;
需要模块自动生成以避免用新元素破坏数据。
如果您需要多次查找,最好将您的数据重组为直接且危险性较小的数据。