arrays - Perl:映射到列表的第一个元素

标签 arrays perl hash map undef

任务:使用 map 构建哈希,其中键是给定数组 @a 的元素,值是某个函数 f($element_of_a) 返回的列表的第一个元素:

my @a = (1, 2, 3);
my %h = map {$_ => (f($_))[0]} @a;

一切正常,直到 f() 返回一个空列表(这对于 f() 来说是绝对正确的,在这种情况下我想分配 undef)。可以使用以下代码重现该错误:
my %h = map {$_ => ()[0]} @a;

错误本身听起来像“散列分配中元素的奇数”。当我重写代码时:
my @a = (1, 2, 3);
my $s = ()[0];
my %h = map {$_ => $s} @a;

或者
my @a = (1, 2, 3);
my %h = map {$_ => undef} @a;

Perl 完全没有提示。

那么我应该如何解决这个问题——当返回的列表为空时,获取 f() 返回的列表的第一个元素?

Perl 版本是 5.12.3

谢谢。

最佳答案

我刚刚玩了一下,似乎()[0] ,在列表上下文中,被解释为空列表而不是 undef标量。例如,这个:

my @arr = ()[0];
my $size = @arr;
print "$size\n";

版画 0 .所以$_ => ()[0]大致相当于 $_ .

要修复它,您可以使用 scalar强制标量上下文的函数:
my %h = map {$_ => scalar((f($_))[0])} @a;

或者你可以附加一个明确的 undef到列表的末尾:
my %h = map {$_ => (f($_), undef)[0]} @a;

或者您可以将函数的返回值包装在一个真正的数组中(而不仅仅是一个平面列表):
my %h = map {$_ => [f($_)]->[0]} @a;

(我个人最喜欢最后一个选项。)

空列表切片的特殊行为记录在 “Slices” in perldata 下。 :

A slice of an empty list is still an empty list. […] This makes it easy to write loops that terminate when a null list is returned:

while ( ($home, $user) = (getpwent)[7,0]) {
    printf "%-8s %s\n", $user, $home;
}

关于arrays - Perl:映射到列表的第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8945859/

相关文章:

linux - 比较两个 excel 表并打印差异?

Perl 以最有效的方式在重复模式上拆分字符串?

regex - Perl 正则表达式问题!

ruby - Sinatra:哈希的未定义方法字节大小

ruby-on-rails - 将以数组为键的 ruby​​ 哈希转换为以单个值作为键的 ruby​​ 哈希的最有效方法

javascript - 如何在JS中从外部url解码多维JSON?

C 数组 - 最大数及其位置

ios - 数组 Swift 中的 ArraySlice

python - 如何在 python 中将 Integer 转换为 64 位大端整数

Ruby 哈希值数组