我还在学习Perl,所以可能有一种更有效的方法。我正在尝试使用哈希值,将其反转为$ values => $ keys,获取新密钥(旧值),然后对这些密钥进行排序。
以下是相关代码:
foreach my $key (sort keys reverse %hash){
...}
我期望发生的是反向%hash将返回一个哈希类型,这是键正在寻找的。但是,我收到以下错误:
arg 1到键的类型必须是哈希(不是反向)
我已经尝试将括号括在反向%hash中,但仍然可以得到相同的东西。
为什么这不起作用的任何想法?
答案 0 :(得分:6)
Perl函数可以返回标量值或列表;没有明确的散列返回类型
(您可以从子例程调用return %hash
,但Perl会隐式地从哈希中展开键值对并将它们作为列表返回)。
因此,reverse %hash
的返回值是列表,而不是散列,不适合用作keys
的参数。您可以强制Perl将此列表解释为具有%{{}}
强制转换的哈希:
foreach my $key (sort keys %{{reverse %hash}}) { ...
您还可以通过说
对哈希值进行排序foreach my $key (sort values %hash) { ...
使用values %hash
与使用keys %{{reverse %hash}}
略有不同,因为keys %{{reverse %hash}}
不会返回任何重复值。
答案 1 :(得分:4)
keys
的参数必须是散列,数组或表达式,而不是列表。如果你做了
keys { reverse %hash }
你会得到你期望的结果,因为括号会创建一个匿名哈希。另一方面,Parens只改变优先权。或者,在这种情况下,它们可能被认为与函数keys()
相关,因为大多数perl函数都有可选的parens。
此外,如果您只想要哈希值,可以使用:
values %hash
答案 2 :(得分:3)
我认为您正在准确描述情况in this example:
#!/usr/local/bin/perl
use strict;
use warnings;
my %hash = (one => 1, two => 2, three => 3, four => 4);
%hash = reverse %hash;
foreach my $key (sort {$a <=> $b} keys %hash) {
print "$key=>$hash{$key}, ";
}
print "\n";
# it displays: 1=>one, 2=>two, 3=>three, 4=>four
答案 3 :(得分:3)
Pre 5.14,keys
返回哈希的键。这需要哈希。你没提供一个。 reverse
不返回哈希值。实际上,返回哈希是不可能的,因为只能返回标量。 (在内部,Perl可以直接在堆栈上放置哈希值,但在用户不会看到“奇怪”错误消息的情况下,用户将永远看不到哈希值。)在编译时检测到此错误。
5.14更灵活。它还将接受对哈希的引用。 (它也会接受数组和对数组的引用,但这里不相关。)引用是标量,因此它们可以由函数返回。您的代码实际上会使其成为运行时,但无论您在标量上下文中返回reverse
,都不会引用不存在的哈希,因此您的代码将在此时死亡。
你有理由想要反转哈希吗?
foreach my $key (sort { $hash{$a} cmp $hash{$b} } keys %hash) {
my $val = $hash{$key};
...
}
如果你这样做,
foreach my $val (sort keys %{ { reverse %hash } }) {
# No access to original key
...
}
或
my %flipped = reverse %hash;
foreach my $val (sort keys %flipped) {
my $key = $flipped{$val};
...
}