Найти имя ключа в хэше только с одним ключом? - PullRequest
28 голосов
/ 11 августа 2011

Если у меня есть хеш

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

и я знаю, что это только один ключ в хэше, но я не знаю, как он называется.

Тогда я сделаюприходится перебирать этот хеш

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

Или есть лучший способ получить имя ключа?

Ответы [ 7 ]

40 голосов
/ 11 августа 2011

A список срезов должен это сделать

(keys %h)[0]

keys возвращает список, поэтому просто извлеките первый элемент этого списка.

14 голосов
/ 11 августа 2011
my ($key) = keys %h;

Поскольку вы используете контекст списка по обе стороны от оператора присваивания, первый элемент в списке ключей назначается на $ key.

10 голосов
/ 11 августа 2011

Я не думаю, что необходимо использовать функцию keys.

my ($key) = %h;

или

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

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

6 голосов
/ 11 августа 2011
my @keys = keys %h;
my $key = $keys[0];
4 голосов
/ 11 августа 2011

[ keys %h ]->[0] также сделает устранение неоднозначности Джоэл упоминает в предыдущем комментарии.Этот код пахнет, как будто он вызовет проблемы, хотя.Если на самом деле существует только одна пара ключ / значение, возможно, есть лучший способ обработки данных.

По крайней мере, я бы хотел убедиться, что ожидание никогда не нарушается молча.Например,

keys %h == 1 or die "ETOOMANYKEYS";
print [ keys %h ]->[0], $/;
3 голосов
/ 15 марта 2017

Давайте взглянем на

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;

Вот с чего мы начали.

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