Perl хэш-значение без имени ключа - PullRequest
0 голосов
/ 14 марта 2012

Возможно ли в Perl получить доступ к значению хеша, если он имеет только один ключ, без использования значения ключа?

Скажем, %h имеет только 'key_name' => 'value'.

Могу ли я получить доступ к 'value' только через $h->{key_name}?

Или, возможно, получить доступ к этому 'value' без имени ключа?

Ответы [ 3 ]

13 голосов
/ 14 марта 2012

Встроенная функция значения для хэшей вернет список всех значений хеш-функции.Вы можете использовать это, чтобы получить или установить любые значения с помощью конструкций списка псевдонимов, таких как foreach, map и grep:

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 голосов
/ 14 марта 2012

Есть много способов сделать это.Например:

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

или

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

Но, на мой взгляд, это не выглядит красиво ...

0 голосов
/ 14 марта 2012

У вас есть два варианта: вы можете оптимизировать пространство или оптимизировать время. Если вам нужно получить ключ из этого значения и вам не важно, сколько времени это займет, вы можете перебрать каждую запись в ассоциативном массиве:

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" ]
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...