2012-03-14 103 views
0

如果没有使用键值,Perl中是否可以访问哈希值(如果它只有一个键)?我们假设%h只有'key_name' => 'value'没有键名的Perl哈希值

我可以只通过$h->{key_name}访问'value'吗?

或者,有可能访问此'value'没有键名?

回答

13

的散列values内置函数将返回所有的散列值的列表。你可以用它来获取或设置的任何值与别名列表构造如foreachmapgrep

for my $value (values %hash) { 
    say $value; # prints the value 
    $value++; # adds one to the value 
} 

或者你也可以存储在一个数组中的值:

my @vals = values %hash; 

的顺序返回的值实际上是随机的,但它将与相应的函数keys的顺序相同。

哈希本身是列表,这样你就可以访问列表环境中的散列的任何奇怪的元素得到的值,但这种方法效率较低,因为整个哈希需要被拆开,形成列表,而不是只价值。

上述技术适用于任何大小的散列。如果你只有一个键/值对:

my %hash = qw(foo bar); 

然后他们减少:

{my ($x) = values %hash; say $x} # bar 
{my (undef, $x) = %hash; say $x} # bar 
{my $x = (values %hash)[0]; say $x} # bar 
{my $x = (%hash)[1];  say $x} # bar 
4

有很多方法可以做到这一点。例如:

my %h=("key_name"=>"value"); print values(%h) 

my %h=("key_name"=>"value"); print((%h)[1]) 

但在我看来并不十分好看......

-2

你有两个选择 - 你可以优化的空间,或优化时间。如果你需要得到该值的键,你不关心它需要多长时间,你可以遍历关联数组中的每个条目:

while(($key, $value) = each(%h)) 
{ 
    if($value eq 'value') 
    { 
     return $key; 
    } 
} 

但是,如果你不介意有两个副本,最省时的解决方案是持有前后联合阵列 - 即:%h_by_name%h_by_value

在这种情况下,如果您有多个具有相同值的密钥,则您的%h_by_value应包含一个数组。也就是说,如果:

%h_by_name = (
    "a" => "1", 
    "b" => "1", 
    "c" => "1", 
    "d" => 2" 
); 

然后你想构建你%h_by_value,以致于它:

%h_by_value = (
    "1" => [ "a", "b", "c" ], 
    "2" => [ "d" ] 
); 
+0

当你的第二个建议,在这种情况下(只有一个键=值对)的作品。只有密钥保证是唯一的,所以你可能会失去使用匹配值的对使用这种方法 – SkryneSaver 2012-03-14 10:55:31

+0

@SkryneSaver:是的,显然如果你有多个唯一键值相同的值,那么你需要添加一个间接级别。仍比循环查看整个哈希值更快。 – 2012-03-14 16:46:31