Как мне обновить значения в массиве хэшей, который находится в хэше хэша в perl? - PullRequest
2 голосов
/ 29 апреля 2011

Кажется, я очень сбиваю с толку.Я попытаюсь «нарисовать» эту структуру данных:

hash-> key -> ((ключ) -> [(ключ, значение), (ключ, значение), (ключ, значение) ,...], (ключ, значение))

Итак, есть первый ключ, значение которого заключено в круглые скобки.Значение для первого ключа хэша - два ключа, один (правый) - другой простой ключ, пара значений.Значение другого (левого) ключа является массивом хэшей.Я могу обновить «правильный» ключ, пару значений со следующей строкой кода:

$hash{$parts[1]}{"PAGES"} += $parts[2];

Где $ parts [1] и $ parts [2] - это просто элементы из массива.Я + = число к «правильному» ключу, пара значений из моего хэша.Что мне нужно сделать сейчас, это обновить «левый» ключ, пара значений - массив хэшей в пределах хэша хэшей.Вот как я инициализирую массив для обеих пар ключ-значение в хэше хэшей:

$hash{$printer}{"PAGES"} = 0;
$hash{$printer}{"USERS"} = [@tmp];

Вот одна из моих многочисленных попыток доступа и обновления значений в массиве хэшей:

$hash{$parts[1]}{"USERS"}[$parts[0]] += $parts[2];

Я просто не могу понять правильный синтаксис для этого.Если бы кто-нибудь мог мне помочь, я был бы благодарен.Спасибо.

Редактировать: Я предполагаю, что более острый вопрос: как мне получить ключ хеша из массива хешей (имея в виду, что массив находится в хэше хэшей)?

Редактировать: Добавил это в код:

#Go through each user to check to see which user did a print job and add the page
#count to their total
#$parts[0] is the user name, $parts[1] is the printer name, $parts[2] is the page
#count for the current print job
for(my $i=0;$i<$arr_size;$i++)
{
    my $inner = $hash{$parts[1]}{"USERS"}[$i];
    my @hash_arr = keys %$inner;
    my $key = $hash_arr[0];

    #problem line - need to compare the actual key with $parts[0]
    #(not the key's value which is a number)
    if($hash{$parts[1]}{"USERS"}[$i]{$key} eq $parts[0])
    {
        $hash{$parts[1]}{"USERS"}[$i]{$parts[0]} += $parts[2];
    }   
}

Редактировать: Упс, хе-хе, это то, что мне нужно.Это еще не совсем там, но это то, что я ищу:

if($key eq $parts[0])
{
    $hash{$parts[1]}{"USERS"}[$i]{$parts[0]} += $parts[2];
}

Ответы [ 4 ]

1 голос
/ 29 апреля 2011

Отредактировано, чтобы ответить на отредактированный вопрос: Как получить ключ хеша из массива хешей (учитывая, что массив находится в хэше хешей). Выход:

$VAR1 = {
     'printer' => {
             'PAGES' => 0,
             'USERS' => [
                   {
                    'a' => 101,
                    'b' => 2
                   },
                   {
                    'c' => 1003,
                    'd' => 1004
                   },
                   {
                    'e' => 9005,
                    'f' => 9006
                   }
                  ]
            }
    };
0 голосов
/ 29 апреля 2011

Я до сих пор не расшифровал вашу структуру. Но я сделаю два комментария:

  1. Используйте синтаксический сахар ->. Например, $hash->{key}->[2]->{key} немного яснее, чем пытаться разобрать вещи без синтаксического сахара: ${{hash}{key}}[1]{key} (если это даже правильно ...)

  2. Изучите использование объектно-ориентированного Perl для этой структуры. Это не так страшно, как кажется. В Perl объекты - это подпрограммы, которые выполняют грязную работу за вас. Взгляните на perldoc perlboot. Это то, что я привык понимать, как работает объектно-ориентированный Perl. Вам даже не нужно создавать полностью отдельный модуль. Определения объектов могут находиться в одном и том же скрипте Perl.

Использование объектно-ориентированного Perl сохраняет беспорядок за пределами вашей основной программы и облегчает поддержку вашей программы. Кроме того, если вам нужно изменить свою структуру, вам не нужно искать весь код, чтобы найти все места для изменения. Синтаксический сахар облегчает понимание того, куда вы движетесь со своей структурой.

Сравните это чудовище с этим объектно-ориентированным чудовищем . Обе программы делают одно и то же. Я написал первый давно, и мне было так трудно его поддерживать, что я переписал его с нуля в объектно-ориентированном стиле. (Это предварительные хуки для Subversion на случай, если кому-то интересно).

0 голосов
/ 29 апреля 2011

То, как вы описали структуру, несколько непонятно для меня, но доступ к ссылкам на массивы, встроенным в другие структуры, осуществляется таким образом, с использованием более простой примерной структуры:

my $ref = {k => [1, 3, 5, 6, 9]};

Ниже значение 6 увеличивается до 7:

$ref->{k}->[3] += 1;

См. perlref для более подробной информации об операторе ->, но вкратце, выражение слева от стрелки может быть любым, которое возвращает ссылку. В некоторых случаях оператор -> является необязательным, но его лучше оставить для ясности.

0 голосов
/ 29 апреля 2011

У меня проблемы с пониманием структуры из вашего описания.

Мой совет - избегать таких структур, как вредные дьяволы из плохих окрестностей.

Одна из причин, по которой люди сталкиваются с такими кошмарами обслуживания -Вы используете XML::Simple.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...