0

Here is my starting point:

#!/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" );

from this I want to make these strings using a loop, if possible without using any trick like building variable names through a loop to get 'hash_a', 'hash_b', 'hash_c'. I was used to use multidimensional arrays for such things in python.

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
2
  • What does "without using any trick like building variable names through a loop to get ...." mean? Are you referring to the names of the hash variables, %hash_a etc? Perhaps you should put all those hashes in another variable, like an array. my @all = ( { num => 7, .... }, { num => 8, .... }, ....); and then loop over the array Commented Nov 22, 2022 at 15:47
  • 1
    Also, you should specify what your question is about. Is it about making the strings, or about looping over the variables? Commented Nov 22, 2022 at 15:49

2 Answers 2

2

I take it your question is more about looping over the variables, and not so much about building the string.

Usually you would not make a bunch of one record hashes and then try to loop over them, like you are doing with %hash_a, %hash_b etc. I would put them all in a single structure, in this case an array:

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" 
});

Then you can simply loop over the array:

for my $record (@all) {
   my $num = $record->{num}; # etc...

And build your string with sprintf

Sign up to request clarification or add additional context in comments.

2 Comments

It's actually an array of hashes. I did not know this was possible in perl. What about @all = { "num" => { 7, 8, 9}, "date" => {...}, ...}?
@user1850133 Hashes are not ordered, so it will not retain the original order of the values. If you want order, you use an array, i.e.: @all = ( num => [ 7, 8, 9 ], date => [ ....] .... The angle brackets [ ... ] create anonymous array references. If you have a preferred identifier to look up records, you can make that the main key in the hash: %all = ( 7 => { date => "22222", prath => "1.1.1", ... }, 8 => { .... } );. Then you can loop over key names for my $key (keys %hash)
0

Here is an example:

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;
}

Output:

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

4 Comments

well, what if i have a lot of hashes such as hash_a, hash_b... having everything in only one variable (or array, or hash) is what seems the right way.
@user1850133 Yes then you put them in an array. you can define an array of hashes like this my @array = (\%hash_a, \%hash_b, ...)
With "a lot" I was meaning, so many that it might be tedious to write the list of variables.
@user1850133 You can also define the array like this my @array = ({a => 1, ...}, {b=>2, ...}, ...) This is an array of hashes also

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.