Как мне создать и добавить анонимные хэши к известному хэшу во время выполнения скрипта?
-
10-07-2019 - |
Вопрос
Я попытаюсь проиллюстрировать это на примере.Возьмем обычный пример хэша хэшей:
my %HoH = (
flintstones => {
lead => "fred",
pal => "barney",
},
jetsons => {
lead => "george",
wife => "jane",
"his boy" => "elroy",
},
simpsons => {
lead => "homer",
wife => "marge",
kid => "bart",
},
);
Для моих целей я хотел бы иметь возможность добавлять неназванные или анонимные хэши в %HOH.Мне не нужно будет (или я не смогу) определять эти подхеши до времени выполнения.Как я могу добиться этого с помощью Perl?
Все, что я прочитал (а я уже прочитал Perldoc и 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.
Решение
Сначала вы создаете хэш из текущей строки, которую вы анализируете
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;
}
Другие советы
Чтобы добавить анонимный хэш во время выполнения, назначьте его так же, как обычный хэш-элемент:
$HoH{key} = { foo => 42 };
или
$HoH{key} = $hash_ref;
или
$HoH{key} = \%hash;
#!/usr/bin/perl
use strict;
my %HoH = (
line01 => {
cell01 => "cell0101",
cell02 => "cell0102",
cell03 => "cell0103"
}
);
$HoH{"line02"} =
{
cell01 => "cell0201",
cell02 => "cell0202",
cell03 => "cell0203"
};
foreach my $hohKey (keys %HoH)
{
my $newHash = $HoH{$hohKey};
print "Line Name: $hohKey\n";
foreach my $key (keys %$newHash)
{
print "\t$key => ", $newHash->{$key}, "\n";
}
}
Каждый раз, когда вы создаете новый хеш из строки данных, вам нужно думать об уникальном ключе для хранения этих данных в вашей верхней хеш-таблице.
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"}
может использоваться для получения определенного фрагмента данных.