以紧凑和(或)快速的方式从哈希映射数组中获取特定键的所有值作为数组

Amo*_*M K 1 arrays perl loops list-comprehension hashmap

我有一个类似的 perl 哈希图

my %data= (
    'John' => {
        'company' => 'xxx',
        'address' => 'San Francisco',
        'contact' => ['phone1', 'phone2']
    },
    'Alice' => {
        'company' => 'yyy',
        'address' => 'Boston',
        'contact' => ['phone3', 'phone4']
    },
);
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以将所有公司名称作为数组提取到一个变量中,而无需遍历哈希图?IE,('xxx', 'yyy')

我已经尝试了以下确实有效的方法,但想要一个更紧凑的解决方案,类似于下面提到的 python 中的列表理解。

@companies = ();
for my $person_data (values %data)
{
    push(@companies, $person_data{'company'});
}
Run Code Online (Sandbox Code Playgroud)

在 python 中,我可以使用列表理解来实现这一点,如下所示: companies = [person_data['company'] for person_data in data.values()]

Tim*_*and 5

与 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
Run Code Online (Sandbox Code Playgroud)

在这里,我使用了一个有效的 Perl 哈希,相当于你展示的 json。我适当地使用了单引号,这是在不需要变量插值的地方。
values %name_to_contact: 返回输入哈希值的无序列表,即匿名哈希列表。
map { $_->{company} } values %name_to_contact: 获取输入散列的值列表,并为每个元素(匿名散列)分配给$_. $_->{company}company这个匿名散列的键值。就是这样!


请注意,您可以map在一条语句中将多个调用链接在一起,这是一种强大的构造,通常比常规循环(如foreach. 然而,在它下面, amap只是另一个循环。:)

  • 从技术上讲,“map”确实循环,就像“for”一样。 (2认同)
  • @TLP 感谢您对“map”和其他循环之间的相似性的评论。将其添加到答案中。 (2认同)