Вот моя отправная точка:
#!/usr/bin/env perl
use warnings;
use strict;
my %hash_a = (
"num" => 7,
"date" => 20221104,
"prath" => "1.1.10",
"antema" => "1.1.15" );
my %hash_b = (
"num" => 8,
"date" => 20221105,
"prath" => "1.1.16",
"antema" => "1.1.19" );
my %hash_c = (
"num" => 9,
"date" => 20221112,
"prath" => "1.1.20",
"antema" => "1.1.39" );
из этого я хочу сделать эти строки с помощью цикла, если это возможно, без использования каких-либо трюков, таких как построение имен переменных через цикл, чтобы получить «хэш_а», «хэш_b», «хэш_с». Я привык использовать многомерные массивы для таких вещей в питоне.
07_class_date_20221104_-_starting_verse_1.1.10_-_closing_verse_1.1.15.mp4
08_class_date_20221105_-_starting_verse_1.1.16_-_closing_verse_1.1.19.mp4
08_class_date_20221112_-_starting_verse_1.1.20_-_closing_verse_1.1.39.mp4
Кроме того, вы должны указать, о чем ваш вопрос. Речь идет о создании строк или о цикле по переменным?
Вот пример:
use feature qw(say);
use strict;
use warnings;
use experimental qw(declared_refs refaliasing);
my %hash_a = (
"num" => 7,
"date" => 20221104,
"prath" => "1.1.10",
"antema" => "1.1.15"
);
my %hash_b = (
"num" => 8,
"date" => 20221105,
"prath" => "1.1.16",
"antema" => "1.1.19"
);
my %hash_c = (
"num" => 9,
"date" => 20221112,
"prath" => "1.1.20",
"antema" => "1.1.39"
);
sub get_str {
my \%hash = $_[0];
sprintf "%02d_class_date_%s_-_starting_verse_%s_-closing_verse_%s.mp4",
$hash{num}, $hash{date}, $hash{prath}, $hash{antema};
}
for my $ref (\%hash_a, \%hash_b, \%hash_c) {
my $str = get_str($ref);
say $str;
}
Выход:
07_class_date_20221104_-_starting_verse_1.1.10_-closing_verse_1.1.15.mp4
08_class_date_20221105_-_starting_verse_1.1.16_-closing_verse_1.1.19.mp4
09_class_date_20221112_-_starting_verse_1.1.20_-closing_verse_1.1.39.mp4
хорошо, что, если у меня есть много хэшей, таких как hash_a, hash_b... иметь все только в одной переменной (или массиве, или хэше) - это то, что кажется правильным.
@ user1850133 Да, тогда вы помещаете их в массив. вы можете определить массив таких хэшей my @array = (\%hash_a, \%hash_b, ...)
Под «много» я имел в виду, так много, что может быть утомительно писать список переменных.
@user1850133 user1850133 Вы также можете определить массив следующим образом my @array = ({a => 1, ...}, {b=>2, ...}, ...)
Это также массив хэшей
Я так понимаю, ваш вопрос больше о переборе переменных, а не о построении строки.
Обычно вы не будете делать кучу хэшей одной записи, а затем пытаться перебирать их, как вы делаете с %hash_a
, %hash_b
и т. д. Я бы поместил их все в одну структуру, в данном случае массив:
my @all = (
{
"num" => 7,
"date" => 20221104,
"prath" => "1.1.10",
"antema" => "1.1.15"
},
{
"num" => 8,
"date" => 20221105,
"prath" => "1.1.16",
"antema" => "1.1.19"
},
{
"num" => 9,
"date" => 20221112,
"prath" => "1.1.20",
"antema" => "1.1.39"
});
Затем вы можете просто перебрать массив:
for my $record (@all) {
my $num = $record->{num}; # etc...
И создайте свою строку с помощью sprintf
На самом деле это массив хэшей. Я не знал, что это возможно в Perl. Как насчет @all = { "num" => { 7, 8, 9}, "date" => {...}, ...}?
@ user1850133 Хеши не упорядочены, поэтому исходный порядок значений не сохранится. Если вам нужен порядок, вы используете массив, то есть: @all = ( num => [ 7, 8, 9 ], date => [ ....] ...
. Угловые скобки [ ... ]
создают ссылки на анонимные массивы. Если у вас есть предпочтительный идентификатор для поиска записей, вы можете сделать его основным ключом в хеше: %all = ( 7 => { date => "22222", prath => "1.1.1", ... }, 8 => { .... } );
. Затем вы можете перебрать имена клавиш for my $key (keys %hash)
Что означает «без использования каких-либо трюков, таких как построение имен переменных через цикл, чтобы получить ...»? Вы имеете в виду имена хэш-переменных,
%hash_a
и т. д.? Возможно, вам следует поместить все эти хэши в другую переменную, например, в массив.my @all = ( { num => 7, .... }, { num => 8, .... }, ....);
, а затем зациклиться на массиве