Perl: Array of hashes - Получить элемент с идентификатором в хэше - PullRequest
0 голосов
/ 27 августа 2018

У меня есть структура данных Perl, загруженная из json, с Data::Dumper, выглядящим так:

    $VAR1 = {
          'Stat' => [
                      {
                        'statCfgFile' => 'statcfg_0001.json',
                        'statid' => 1,
                        'status' => 'running',
                        'something' => 'other'
                      },
                      {
                        'statCfgFile' => 'statcfg_0002.json',
                        'statid' => 2,
                        'status' => 'running'
                        'something' => 'other'
                      }
           ]
}

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

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

Есть ли способ прямого доступа к элементу массива с помощью statid, хранящегося в хэше?

Поскольку модель данных находится в моих руках и в настоящее время находится в разработке: Не лучше ли использовать массив, но также хеш с statid в качестве элемента именования?

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Короткий ответ - нет, вы не можете извлечь значение из массива на основе критериев, не выполняя итерацию по массиву. Но есть способы написать это без использования цикла.

Скажем, структура данных $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]; 
0 голосов
/ 27 августа 2018

Если поле statid уникально, я предлагаю вам использовать что-то более похожее на это

{
    1 => 'statcfg_0001.json',
    2 => 'statcfg_0002.json',
}

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

Тогда вам нужен хеш вместо просто строкового значения для каждого statid

{
    1 => {
        statCfgFile => 'statcfg_0001.json',
        statid      => 1,
        status      => 'running',
        something   => 'other',
    },
    2 => {
        statCfgFile => 'statcfg_0002.json',
        statid      => 2,
        status      => 'running',
        something   => 'other',
    },
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...