Преобразование хеша в массив на perl

Я хочу изменить этот код с использования хеша на массив, но я не могу найти хороший пример для продолжения. Кто-нибудь может посоветовать? Пока я только намекаю на использование [ ] во второй строке.

my @subscriptions    = ();
$self->{'serverMap'} = {};

foreach my $service( "pmservice", "saservice" ) {

    my $r_serverMap = enmGetServiceGroupInstances($self->{'site'}, $self->{'date'}, $service);

    while ( my ($server, $serverId) = each %{$r_serverMap} ) {
        push ( @subscriptions, {'server' => $server, 'prog' => 'JBOSS'} );
        $self->{'serverMap'}->{$server} = $serverId;
    }
}

return \@subscriptions;

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

Borodin 30.07.2018 12:25
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
2
1
81
2

Ответы 2

Во-первых, эти два назначения не нужны:

my @subscriptions    = ();
$self->{'serverMap'} = {};

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

my @subscriptions;

тогда он создается пустым. Добавление = () к определению ничего не дает.

И явная установка $self->{'serverMap'} как пустого анонимного хеша бесполезна. Когда вы начинаете помещать данные в $self->{'serverMap'}, вы можете решить, в каком формате должны быть эти данные.

Во-вторых, вы говорите, что хотите заменить хеш массивом. Я предполагаю, что это хэш, который в настоящее время хранится в $self->{'serverMap'}, который вы хотите заменить. Это просто. Просто замените строку:

$self->{'serverMap'}->{$server} = $serverId;

с участием

push @{ $self->{'serverMap'}->{$server} }, $serverId;

Фактически, давайте избавимся от всей этой ненужной пунктуации одновременно:

push @{ $self->{serverMap}{$server} }, $serverId;

Готово. Первоначально $self->{'serverMap'} содержал ссылку на хэш, теперь он содержит ссылку на массив.

Конечно, это только половина дела. Теперь вы храните данные как массив, но вам также необходимо получить доступ к данным как к массиву. Где-то в вашем коде вы будете смотреть на данные в $self->{'serverMap'} - и теперь их тоже нужно изменить, иначе ваша программа перестанет работать.

См. Также предыдущий вопрос этого парня Преобразование кода с использованием хеша в массив

Borodin 30.07.2018 13:45

Всегда присваивайте значение своим переменным. Несколько лет назад mod_perl использовался для повторного использования пространства данных без его повторной инициализации. Переменные, которым не было присвоено значение при объявлении, будут использовать значение из предыдущего запуска. Эта проблема была исправлена, но кто знает, когда появится новая идея, которая будет делать то же самое. Возьмите в привычку программировать в защитной манере: всегда присваивайте значение своим переменным.

shawnhcorey 30.07.2018 14:00

@shawnhcorey: Прошло много времени, и я успешно забыл большую часть того, что знал о mod_perl, но разве он не использовал повторно только переменные пакета? Он видит вашу программу как подпрограмму, поэтому любые лексические переменные будут правильно инициализированы.

Dave Cross 30.07.2018 14:11
«Всегда присваивайте значение своим переменным» Чепуха. Защитное программирование разумно, но это всего лишь один пример из бесконечного "новые идеи", который вы решили, сделав свой код излишне более шумным. Если вы используете новая вещь, вам следует знать, какие проблемы он может принести с собой. Не дай Бог, чтобы каждая программа Perl содержала все взломы для защиты от любого возможного неправильного поведения ее среды. В любом случае это явно не программа mod_perl.
Borodin 30.07.2018 15:28

@ Дэйв: "разве это не только повторное использование переменных пакета" Я думаю, это очень вероятно. Простое сохранение и перезагрузка образа памяти вряд ли восстановит лексические данные в кадре стека, потому что это мобильный, и я думаю, что Apache умнее этого. Восстановление переменных пакета кажется хорошей идеей, если вы знаете, что это происходит.

Borodin 30.07.2018 15:31

@Borodin Apache не было, но теперь он есть. И это не «новая» идея. Ему более 50 лет. А когда дело доходит до программистов, это не имеет значения. Сделайте все явным. «Шумный» лучше, чем расплывчатый.

shawnhcorey 30.07.2018 18:07

@shawn: Итак, вы говорите, что Apache "вещь" устарел и исправлен, но мы все равно должны кодировать его, вместе с любыми "новые вещи", которые имеют ту же ошибку и которые могут быть наложены на нашу программу без нашего ведома? Это еще хуже. Придерживайтесь C.

Borodin 30.07.2018 19:45

@shawn: Вы также инициализируете все скалярные переменные нулями 0 или пустой строкой ""? Теперь возникает загадка: что это должно быть? И мир погибнет, если mod_perl или что-то столь же неприятное установит его на undef. Что нам следует сделать?

Borodin 30.07.2018 19:57

такой же, но выглядит короче

my @subscriptions;
foreach my $service( "pmservice", "saservice" ) {
    $self->{serverMap} = enmGetServiceGroupInstances($self->{'site'}, $self->{'date'}, $service);

    push @subscriptions, map {
        +{ server => $_, prog => 'JBOSS' }
    } keys %{ $self->{'serverMap'} };
}

Другие вопросы по теме