Если по значению нужно найти ключ, то придется рекурсивно обойти весь хеш и сверить. При этом ключей может быть больше одного. Но вопрос в другом: зачем это нужно? Почему бы просто не передать и ключ и значение туда, где это нужно? Или создать таблицу для обратного поиска.
Met vriendelijke groet, Alex On Tue, Oct 1, 2024 at 7:24 PM Alessandro Gorohovski via Moscow-pm < [email protected]> wrote: > > вт, 1 окт. 2024 г. в 15:03, Коваль Вячеслав <[email protected]>: > >> Смотри, во-первых, в данном случае нет необходимости разыменовывать хэш и >> брать из него ссылку. Можено сразу передавать нужный хэш: $h{aa}. >> > > Да, согласен, конечно можно и нужно так. Спасибо. > Просто хотел этой конструкцией дополнительно выделить цель и обратить на > неё внимание. > > >> Во-вторых, в функцию (в нижеприведенном коде вместо функции выступает >> переменная $val) мы уже передаем ссылку на хэш >> { bb => 2 }. Функция ничего не знает о ключе, он есть только в хэше. >> >> > > Понимаете, здесь проблема не в том, чтобы узнать какие ключи-потомки есть > в передаваемой ссылке, > а узнать именно родительский ключ '*aa*'. > > >> #!/usr/bin/perl -w >> use strict; >> use warnings; >> use feature 'say'; >> >> use DDP; >> use Scalar::Util qw/refaddr/; >> >> my %h = ( a => { b => 1 }, aa => { bb => 2 } ); >> p %h; >> say refaddr $h{aa}; >> my $val = $h{aa}; >> p $val; >> say refaddr $val; >> say refaddr $h{aa} == refaddr $val; >> > > К сожалению это всё предполагает, что вы *наперед знаете о том, что > родительский ключ 'аа'* > и ожидаете когда ссылка на него появится. > А если неизвестно заранее как называется родительский ключ? > Известно только, что такой ключ единственный. > > > >> >> Как вариант можно передавать предыдущее значение, где есть ключ. >> >> my %h = (aa => { bb => { cc => 3}}); >> where_key('bb', $h{aa}); >> >> > Здесь, честно говоря, не понятно как эта функция вернёт ключ 'aa' ? > > > >> Либо передавать исходных хэш: >> >> where_key($искомая_ссылка, \%h); >> > > Теоретически возможно, хотя чрезвычайно сложно и > здесь придётся искать совпадения адресов с передаваемым ссылкой > по всему хешу с неизвестной структурой. > > Я предполагал, что можно получить доступ к некой "глобальной" таблице с > описанием связей > 'ключ' => 'адрес' или наоборот. > А зная адрес найти нужный 'ключ'. > > >> ---------------- >> 01.10.2024, 14:44, "Alessandro Gorohovski" <[email protected]>: >> Кому: Коваль Вячеслав ([email protected]); >> Копия: Moscow.pm group ([email protected]); >> Тема: [Moscow.pm] Узнать родительский ключ по ссылке; >> >> >> Вообще то передаётся ссылка (фактически адрес) >> >> \%{ $h{aa} } >> >> , а не просто значение. >> >> вт, 1 окт. 2024 г. в 14:37, Коваль Вячеслав <[email protected]>: >> >> Для решения задачи все равно нужен доступ к исходному хэшу, т.к. в >> изначальном коде мы передаем уже обращаемся по ключу и в функцию уже >> передается значение, т.е. какой-то хэш или массив или значение. А чтобы >> получить ключ, то нужно рекурсивно пройтись по исходному хэшу и сравнить >> Scalar::Util::refaddr всех значений с исходным. >> >> ---------------- >> 01.10.2024, 13:47, "Alessandro Gorohovski via Moscow-pm" < >> [email protected]>: >> Кому: Moscow.pm group ([email protected]); >> Копия: Alessandro Gorohovski ([email protected]); >> Тема: [Moscow.pm] Узнать родительский ключ по ссылке; >> >> >> Нет, это не вариант. >> Функция не знает о хеше %h и его структуре, совсем не знает :) >> >> Представьте, что этот хеш может быть не 2х уровневый, а >> много-много-вложенный по уровням >> и >> $ref eq $value >> может случится на другом уровне. >> >> >> вт, 1 окт. 2024 г. в 13:03, Steffen Winkler via Moscow-pm < >> [email protected]>: >> >> use strict; >> use warnings; >> >> my %h = ( a => { b=> 1}, aa=> {bb=>2, }, ); >> >> sub where_key { >> my $ref = shift; >> >> while ( my ($key, $value) = each %h ) { >> $ref eq $value >> and return $key; >> } >> >> return; >> } >> >> my $k = where_key( $h{aa} ); >> print $k; >> exit; >> >> >> -- >> Moscow.pm mailing list >> [email protected] | http://moscow.pm.org >> >> ,-- >> Moscow.pm mailing list >> [email protected] | http://moscow.pm.org >> >> >> >> >> >> -- >> Яндекс.Почта — надёжная почта >> http://mail.yandex.ru/neo2/collect/?exp=1&t=1 >> >> >> >> >> >> -- >> Яндекс.Почта — надёжная почта >> http://mail.yandex.ru/neo2/collect/?exp=1&t=1 >> > -- > Moscow.pm mailing list > [email protected] | http://moscow.pm.org >
-- Moscow.pm mailing list [email protected] | http://moscow.pm.org
