Короткий ответ - нет, вы не можете извлечь значение из массива на основе критериев, не выполняя итерацию по массиву. Но есть способы написать это без использования цикла.
Скажем, структура данных $data
, и вы хотите получить хеши, где statid
равно $id_to_find
.
my @matching_hashes = grep {$_->{statid} = $id_to_find}} @{$data->{Stat}};
Если релевантен только первый хэш, соответствующий идентификатору, вы можете использовать базовый модуль List::Util
function first
, который делает то же самое, что и grep
, но возвращает только первое совпадение вместо списка. Это будет быстрее, чем grep
, потому что он прекращает итерацию по массиву, как только находит одно совпадение.
use List::Util 'first';
my $matching hash = first {$_->{statid} = $id_to_find}} @{$data->{Stat}};
Как вы указали, использование поиска по хешу намного быстрее, чем операции со списком. Вы можете создать хэш-индекс адресов массивов. Обратите внимание, что это все еще требует, чтобы вы перебрали массив.
# create the index;
my %index;
my @array = @{$data->{Stat}};
for my $address (0..$#array) { # "$#array" is the last element of @array
my $hash = $array[$address];
my $id = $hash->{statid};
$index{$id} = $address; # now you can use an ID to get the array address
}
# use the index
my $id_to_find = 42;
my $wanted_array_address = $index{$id_to_find};
my $matching_hash = $data->{Stat}->[$wanted_array_address];