【问题标题】:Obtaining all values of particular key as an array from an array of hashmaps in a compact and(or) quick way以紧凑和(或)快速的方式从哈希映射数组中获取特定键的所有值作为数组
【发布时间】:2021-01-09 15:10:40
【问题描述】:

我有一个 perl 哈希表

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

有没有一种方法可以将所有公司名称作为数组提取到一个变量中,而无需遍历哈希图? 即('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()]

【问题讨论】:

  • 你尝试过什么,你在哪里卡住了?另外,请注意,您的数据结构看起来不像 Perl 哈希,而是像 JSON 字符串,这让您的问题有点不清楚。
  • 我是说 Perl 哈希是从我上面提到的那种 JSON 加载的。显然,我尝试循环遍历哈希并将公司名称推送到数组中。但我需要知道是否有更清洁、更快的方法来做到这一点。例如:可以使用简单的%hash = map { $_ => 1 } @array; 将数组转换为散列 在python 中,即使我仍然循环遍历散列/字典,我也可以在一行中编写代码,如下companies = [value['company'] for value in data.values()]。如果我也能在 Perl 中做同样的事情就足够了。
  • 请在下次显示有效的 Perl 哈希而不是 json。很清楚您想要做什么,但是 Perl 散列可以为想要回答问题的人节省时间。请参阅我的问题中的示例。您也可以使用 Data::Dumper 模块从您的代码中获取它。 :)

标签: arrays loops perl hashmap list-comprehension


【解决方案1】:

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:返回输入哈希值的无序列表,即匿名哈希列表。
@987654326 @ :获取输入哈希值的列表,并将每个元素(匿名哈希)分配给$_$_->{company} 是此匿名哈希的 company 键的值。就是这样!


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

【讨论】:

  • 技术上,map 确实循环,就像for
  • @TLP 感谢您对map 与其他循环之间的相似性的评论。将此添加到答案中。
【解决方案2】:

你不应该在没有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,您就可以避免这个问题。

【讨论】:

    猜你喜欢
    • 2016-05-29
    • 2021-06-11
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多