为什么这个 reduce {} 没有按预期返回最大值?

Why is this reduce {} not returning the max value as expected?

我需要找到 Perl 散列中所有值的最大值。我不需要密钥,只需要最高值,这样我就可以增加它和 return 一个比以前更高的新值。世界上最简单的事情。我从这个答案中得到启发:,并实现了这段代码:

use List::Util qw( reduce min max );
my %gid = ("abc" => 1, "def" => 1);
my $gid_ref = \%gid;
my $max_gid = reduce { $a > $b ? $a : $b } values %$gid_ref || 0;
print "$max_gid\n"; 

如您所见,哈希仅包含两个 1 作为值。那为什么要打印“2”呢?至少在我的机器上是这样。

我想我可以写

my $max2 = max(values %$gid_ref) || 0;

无论如何要获得最大值,但我真的很想了解这里发生了什么。

这一行

my $max_gid = reduce { $a > $b ? $a : $b } values %$gid_ref || 0;

被解析为

my $max_gid = reduce { $a > $b ? $a : $b } (values %$gid_ref || 0);

(values %$gid_ref || 0)

在标量上下文中使用 values,其计算结果为散列 (2) 中的元素数。由于 2 || 0 仍然是 2,您对标量执行归约并取回值。

另一方面

my $max_gid = (reduce { $a > $b ? $a : $b } values %$gid_ref) || 0;

确实按预期获得了序列的最大值。

|| 0 的目的到底是什么?文档推荐

If your algorithm requires that reduce produce an identity value, then make sure that you always pass that identity value as the first argument to prevent undef being returned.

所以你可能想要

my $max_gid = reduce { $a > $b ? $a : $b } 0, values %$gid_ref;

您还可以使用较低优先级的 or 运算符代替 ||,这不会对 values()

施加标量上下文
my $max_gid = (reduce { $a > $b ? $a : $b } values %$gid_ref or 0);

(此处括号为必填项,省略则警告)