Perl 在只有一个键的哈希中查找键名?

Perl 在只有一个键的哈希中查找键名?,perl,hash,Perl,Hash,如果我有杂烩 my %h = ( secret => 1; ); 我知道散列中只有一个键,但我不知道它叫什么 然后我必须遍历该散列吗 my $key; foreach my $i (keys %h) { $key = $h{$i}; } 或者有更好的方法来获取密钥的名称吗?a应该这样做 my @keys = keys %h; my $key = $keys[0]; (keys %h)[0] keys返回一个列表,因此只需提取该列表的第一个元素。我认为没有必要使用ke

如果我有杂烩

my %h = (
    secret => 1;
);
我知道散列中只有一个键,但我不知道它叫什么

然后我必须遍历该散列吗

my $key;
foreach my $i (keys %h) {
    $key = $h{$i};
}
或者有更好的方法来获取密钥的名称吗?

a应该这样做

my @keys = keys %h;
my $key = $keys[0];
(keys %h)[0]

keys
返回一个列表,因此只需提取该列表的第一个元素。

我认为没有必要使用
keys
功能

my ($key) = %h;


paren中的散列将扩展为一个列表,然后我们只需获取该列表的第一个元素,即键。

[keys%h]->[0]
还将执行前面注释中提到的消歧操作。但这段代码闻起来好像会引起问题。如果实际上只有一个键/值对,那么可能有更好的方法来处理数据

至少,我会检查一下,以确保这种期望永远不会被默默地违背。例如&dash

keys %h == 1 or die "ETOOMANYKEYS";
print [ keys %h ]->[0], $/;
但是,如果要在同一哈希上再次使用迭代器,则必须记住重置迭代器。或者另一个
每个
都会这样做,或者
会这样做,如果在标量上下文中使用,将避免创建列表。所以你可以用

scalar keys %h; 
# OR
each %h;          # <- gets the undef
my $k2 = each %h; # <- gets the first key
但是假设它就像阅读JSON消息一样,你只想读一次散列中的内容然后扔掉,那么它可能是最简洁的。但是,如果您希望立即使用变量,则执行此操作可能更容易:

my ( $k, $v ) = each %$simple_JSON_structure;

当您在赋值运算符的两侧使用列表上下文时,键列表中的第一项被赋值给$key。

让我们看看

my ($key) = %h;
散列和数组并不像看上去那样不同。它们都与列表密切相关。使用列表是它们正常初始化的方式,
=>
主要是
的别名,唯一的区别是它将其左操作数隐式引用。Perl只有在忘记其右操作数的引号时才会停止,因此将接受以下两行:

my %h = (a=>b=>c=>'d');
my @a = (a=>b=>c=>'d');
你试过这个吗

my %h = ('key');
……或者:

my @a = ('value');
my %h = @a;
上面的散列可能看起来有点奇怪,但它只是一个值为
undef
的键

因为您很可能会询问如何访问单个值,所以我建议使用:

my ($key, $value) = %h;
…甚至更简单:

my ($key) = %h;

这就是我们开始讨论的问题。

使用此方法唯一需要注意的是“看起来像函数”问题。为了避免这种情况,您可能需要
((键%h)[0])
例如
perl-E'my%h=(secret=>1);说出(键%h)[0];'失败,但
perl-E'my%h=(secret=>1);说((键%h)[0]);'工作。问题是perl看到
say
()
,因此解析为
(say(key%h))[0]
。所以要小心,没有数组被返回,也没有引用被取消引用。修复了术语,并添加了相关文档的链接。这是一个很棒的答案。拯救了我的一天:)谢谢,在void上下文中的lotkey也可以工作(并且对于绑定哈希会更有效),我同意这可以工作。我认为这是一个“过份聪明”的例子,给Perl起了一个坏名声。
my($x)=%h
整体上太聪明了吗?到目前为止,给出的答案(包括公认的答案)都有很多。它也很短,容易理解和记忆。
my %h = ('key');
my @a = ('value');
my %h = @a;
my ($key, $value) = %h;
my ($key) = %h;