以紧凑和(或)快速的方式从哈希映射数组中获取特定键的所有值作为数组
Obtaining all values of particular key as an array from an array of hashmaps in a compact and(or) quick way
我有一个 perl 散列表
my %data= (
'John' => {
'company' => 'xxx',
'address' => 'San Francisco',
'contact' => ['phone1', 'phone2']
},
'Alice' => {
'company' => 'yyy',
'address' => 'Boston',
'contact' => ['phone3', 'phone4']
},
);
有没有一种方法可以将所有公司名称作为数组提取到一个变量中,而无需循环遍历 hashmap?
即 ('xxx', 'yyy')
我已经尝试了以下确实有效的方法,但我想要一个更紧凑的解决方案,类似于下面提到的 python 中的列表理解。
@companies = ();
for my $person_data (values %data)
{
push(@companies, $person_data{'company'});
}
在 python 中,我可以使用列表推导式实现这一点,如下所示:
companies = [person_data['company'] for person_data in data.values()]
Python 列表理解的 Perl 等效项是 map
,因此您可以使用 @companies = map { $_->{company} } values %name_to_contact;
.
示例:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw( say );
my %name_to_contact = (
'John' => {
'company' => 'xxx',
'address' => 'San Francisco',
'contact' => ['phone1', 'phone2']
},
'Alice' => {
'company' => 'yyy',
'address' => 'Boston',
'contact' => ['phone3', 'phone4']
},
);
my @companies = map { $_->{company} } values %name_to_contact;
say "@companies";
# Prints:
# xxx yyy
在这里,我使用了一个有效的 Perl 散列,相当于您显示的 json。我酌情使用了单引号,这是在不需要变量插值的地方。
values %name_to_contact
: returns 输入哈希值的无序列表,即匿名哈希列表。
map { $_->{company} } values %name_to_contact
:获取输入哈希的值列表,并将每个元素(匿名哈希)分配给 $_
。 $_->{company}
是此匿名散列的 company
键的值。就是这样!
请注意,您可以在单个语句中将 map
的多个调用链接在一起,这是一个强大的结构,通常比 foreach
等常规循环更可取。然而,在它下面,一个 map
只是另一个循环。 :)
你不应该 运行 没有 use strict; use warnings;
的代码。如果你有,你会得到这个致命错误:
Global symbol "%person_data" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
在此代码中,您缺少箭头运算符,当散列位于标量值内时使用该箭头运算符,就像在您的代码中一样。换句话说:
$person_data{'company'}
应该是这样的:
$person_data->{'company'}
前者指的是一个散列,应该这样声明:
my %person_data;
如果你使用过strict
,你就可以避免这个问题。
我有一个 perl 散列表
my %data= (
'John' => {
'company' => 'xxx',
'address' => 'San Francisco',
'contact' => ['phone1', 'phone2']
},
'Alice' => {
'company' => 'yyy',
'address' => 'Boston',
'contact' => ['phone3', 'phone4']
},
);
有没有一种方法可以将所有公司名称作为数组提取到一个变量中,而无需循环遍历 hashmap?
即 ('xxx', 'yyy')
我已经尝试了以下确实有效的方法,但我想要一个更紧凑的解决方案,类似于下面提到的 python 中的列表理解。
@companies = ();
for my $person_data (values %data)
{
push(@companies, $person_data{'company'});
}
在 python 中,我可以使用列表推导式实现这一点,如下所示:
companies = [person_data['company'] for person_data in data.values()]
Python 列表理解的 Perl 等效项是 map
,因此您可以使用 @companies = map { $_->{company} } values %name_to_contact;
.
示例:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw( say );
my %name_to_contact = (
'John' => {
'company' => 'xxx',
'address' => 'San Francisco',
'contact' => ['phone1', 'phone2']
},
'Alice' => {
'company' => 'yyy',
'address' => 'Boston',
'contact' => ['phone3', 'phone4']
},
);
my @companies = map { $_->{company} } values %name_to_contact;
say "@companies";
# Prints:
# xxx yyy
在这里,我使用了一个有效的 Perl 散列,相当于您显示的 json。我酌情使用了单引号,这是在不需要变量插值的地方。
values %name_to_contact
: returns 输入哈希值的无序列表,即匿名哈希列表。
map { $_->{company} } values %name_to_contact
:获取输入哈希的值列表,并将每个元素(匿名哈希)分配给 $_
。 $_->{company}
是此匿名散列的 company
键的值。就是这样!
请注意,您可以在单个语句中将 map
的多个调用链接在一起,这是一个强大的结构,通常比 foreach
等常规循环更可取。然而,在它下面,一个 map
只是另一个循环。 :)
你不应该 运行 没有 use strict; use warnings;
的代码。如果你有,你会得到这个致命错误:
Global symbol "%person_data" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
在此代码中,您缺少箭头运算符,当散列位于标量值内时使用该箭头运算符,就像在您的代码中一样。换句话说:
$person_data{'company'}
应该是这样的:
$person_data->{'company'}
前者指的是一个散列,应该这样声明:
my %person_data;
如果你使用过strict
,你就可以避免这个问题。