2011-08-11 173 views
21

如果我有一个哈希只用一个密钥在密钥中查找密钥名称?

my %h = (
    secret => 1; 
); 

,我知道,这只是在哈希一个关键,但我不知道它叫什么。

难道我有那么通过哈希

my $key; 
foreach my $i (keys %h) { 
    $key = $h{$i}; 
} 

迭代或者有没有更好的方式来拿到钥匙的名字吗?

+0

比迄今为止给出的所有答案(包括已接受的答案)都有[更容易的解决方案](http://stackoverflow.com/a/42809337/2932052)。它也更短,易于理解和记忆。 – Wolf

回答

34

一个list slice应该这样做

(keys %h)[0] 

keys返回一个列表,所以只提取列表的第一个元素。

+7

唯一需要注意的方法是“看起来像一个功能”问题。为了避免这种情况,你可能需要'((keys%h)[0])'例如'perl -E'my%h =(secret => 1);说(键%h)[0];''失败,但'perl -E'我的%h =(秘密=> 1);说((键%h)[0]);''工作。问题是perl看到'say'和一个'()',因此解析为'(比如说(键盘%h))[0]'。所以只是要小心。 –

+4

没有数组被返回或引用被取消引用。修正了术语并添加了相关文档的链接。 – ikegami

6
my @keys = keys %h; 
my $key = $keys[0]; 
8

我不认为有必要使用keys函数。

my ($key) = %h; 

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

的括号内的哈希值将扩展到列表,然后我们可以简单地采取这一名单,这是关键的第一要素。

+1

我同意这会起作用。我认为这是一个“太聪明”的例子,给了Perl一个不好的名字。 –

+0

什么,你觉得这太聪明了一半? – TLP

+0

那么我的($ x)=%h'太聪明了吗? –

4

[ keys %h ]->[0]也会在之前的评论中提到消歧Joel。这段代码闻起来会引起问题。如果实际上只有一个键/值对,那么可能有更好的方法来处理数据。

至少,我会检查以确保预期永远不会违反。例如。 ‐

keys %h == 1 or die "ETOOMANYKEYS"; 
print [ keys %h ]->[0], $/; 
2
my $k = each %h; 

但是,你必须记住将迭代器,如果你想再次使用它在相同的散列。要么是另一个each会这样做,要么keys会,并且如果在标量上下文中使用,将避免创建列表。所以,你可以用

scalar keys %h; 
# OR 
each %h;   # <- gets the undef 
my $k2 = each %h; # <- gets the first key 

所以重新设置,你可以做这样的:

my $k = (scalar keys %h, each %h); 

不过,假设它就像读JSON消息之类的东西,你只是想读什么是哈希一次就扔它可能是最简洁的。但是,如果你想变的时候了,它可能更容易做到这一点:

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

无效上下文中的键也起作用(并且对于连接的散列将更有效) – ysth

+0

[但是,不要忘记随后使用键(%散列)重置迭代器,否则后续每个键都会失败。](https:// stackoverflow。 COM /职位/ 42809852 /修订版) – Wolf

12
my ($key) = keys %h; 

当你使用赋值运算符两边列表上下文,在键列表中的第一项获得分配给$键。

1

让我们必须在

my ($key) = %h; 

哈希看看和数组并不像看上去那么不同。他们都与名单密切相关。使用列表是他们正常初始化的方式,并且=>主要是,的别名,唯一区别在于它隐式引用左引号。

my %h = (a=>b=>c=>'d'); 
my @a = (a=>b=>c=>'d'); 

那么,你有没有尝试这个办法:Perl的只有当你忘记它的右操作数的报价,所以下面的两条线将被接受停止?

my %h = ('key'); 

...或这个:

my @a = ('value'); 
my %h = @a; 

哈希上述可能看起来有点怪,但它只是一个价值undef关键。

因为它是最有可能你会问如何访问单个值,我建议使用:

my ($key, $value) = %h; 

...或者更简单:

my ($key) = %h; 

这就是我们开始。