Как создать и добавить анонимные хэши к известному хешу во время выполнения скрипта?

Я попытаюсь проиллюстрировать это на примере. Возьмем общий пример хэша хэшей:

my %HoH = (
    flintstones => {
        lead => "fred",
        pal  => "barney",
    },
    jetsons => {
        lead      => "george",
        wife      => "jane",
        "his boy" => "elroy",
    },
    simpsons => {
        lead => "homer",
        wife => "marge",
        kid  => "bart",
    },
);

Для моих целей я хотел бы иметь возможность добавлять безымянные или анонимные хэши в %HOH. Мне не нужно (и я не смогу) определять эти подхэши до времени выполнения. Как я могу сделать это с помощью Perl?

Все, что я читал (и я уже читал Perldocs и Google), кажется, показывает примеры, где определены все суб-хахи (например, «флинтстоуны», «джетсоны» и «симпсоны»).

Что я делаю, так это пытаюсь создать родительский хеш, который будет содержать вложенные хэши со строками из файла CSV:

%TopHash = (
   %Line1 => {
      cell01 => $some_value1a;
      cell02 => $some_value2a;
      cell03 => $some_value3a;
   },
   %Line2 => {
      cell01 => $some_value1b;
      cell02 => $some_value2b;
      cell03 => $some_value3b;
   },
   %Line3 => {
      cell01 => $some_value1c;
      cell02 => $some_value2c;
      cell03 => $some_value3c;
   },
# etc
# etc
# etc

    );

Количество хэшей "%LineX", которое мне нужно, неизвестно до момента выполнения (поскольку они представляют собой количество строк в CSV, которое считывается во время выполнения).

Любые идеи? Если это еще не ясно... Я все еще пытаюсь понять хэши Perl.


person Mick    schedule 29.10.2009    source источник
comment
Кстати, вы уверены, что хотите использовать HoH для этой структуры? Поскольку вы анализируете файлы CSV, похоже, что хэш массивов может подойти лучше. В общем, если вы обнаружите, что вставляете последовательные числа в конце ключа хеша или имени переменной, вам, вероятно, следует использовать массив.   -  person friedo    schedule 29.10.2009
comment
Моя конечная цель - получить список строк с уникальными данными (определяемыми комбинацией 3 ячеек подряд); однако мне нужны все ячейки уникальных строк. Может быть, для этой задачи лучше подойдет массив хэшей?   -  person Mick    schedule 29.10.2009
comment
У вас уже есть много ответов, но я не видел, чтобы кто-нибудь указывал вам на Поваренную книгу по структурам данных (perldoc perldsc) perldoc.perl.org/perldsc.html содержит множество примеров работы со сложными структурами данных. Конечно, вы, возможно, уже видели его, так как читали perldoc.   -  person daotoad    schedule 29.10.2009


Ответы (3)


Сначала вы создаете хеш из текущей строки, которую вы анализируете

my %lineHash = (
    cell01 => $some_value1a,
    cell02 => $some_value1b,
    cell03 => $some_value1c
);

или создать ссылку на хеш сразу

my $lineHashRef = {
    cell01 => $some_value2a,
    cell02 => $some_value2b,
    cell03 => $some_value2c
};

Затем вы добавляете его к общему хэшу, помня, что вложенные структуры Perl просто содержат ссылки на другие структуры.

$topHash{line1} = \%lineHash;
$topHash{line2} = $lineHashRef;

Обновлен Пример с циклом по массиву данных для анализа

my %topHash;
foreach my $i (0 .. $#data) {
    my %tempHash;
    // stuff here to parse $data[$i] and populate %tempHash
    $topHash{"line$i"} = \%tempHash;
}
person jamessan    schedule 29.10.2009
comment
Моя проблема в том, что я не знаю, сколько %lineHash мне нужно, потому что оно привязано к количеству строк в CSV, прочитанном во время выполнения. - person Mick; 29.10.2009
comment
Так в чем проблема? Вы можете сказать $topHash{"line$line"} = $lineHashRef и продолжать увеличивать $line каждый раз, когда создаете анонимный хэш из строки в файле CSV. - person mob; 29.10.2009

Чтобы добавить анонимный хэш во время выполнения, назначьте его так же, как обычный хеш-элемент:

$HoH{key} = { foo => 42 };

or

$HoH{key} = $hash_ref;

or

$HoH{key} = \%hash;
person friedo    schedule 29.10.2009

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

my $line = 1;
my %HoH;
while (<>) {
    my ($cell01, $cell02, $cell03, @etc) = split /,/;
    my $newHash = { cell01 => $cell01, cell02 => $cell02, ... };
    my $key = "line$line";
    $HoH{$key} = $newHash;
    $line++;
}

Теперь keys(%HoH) вернет (несортированный) список, например "line1","line2","line3",....
$HoH{"line5"} вернет ссылку на данные для 5-й строки вашего файла.
%{$HoH{"line7"}} — довольно уродливый синтаксис, но он возвращает хэш-таблицу ваших данных из строки 7.
$HoH{"line14"}{"cell02"} можно использовать для получения определенный фрагмент данных.

person mob    schedule 29.10.2009