Dynamically creating arrays in Perl

I want to create arrays dynamically based on user input. For example, if the user enters input as 3, then you need to create three arrays with the names @message1 , @message2 and @message3 .

How do I do this in Perl?

+7
arrays perl
source share
4 answers

not to do. Use an array of arrays instead:

 my @message; my $input = 3; for my $index ( 0..$input-1 ) { $message[$index][0] = "element 0"; $message[$index][1] = 42; } print "The second array has ", scalar( @{ $message[1] } ), " elements\n"; print "They are:\n"; for my $index ( 0..$#{ $message[1] } ) { print "\t", $message[1][$index], "\n"; } 

Some useful rules are at http://perlmonks.org/?node=References+quick+reference

+17
source share

I have to ask why you want to do this because this is not the right way. If you have three input streams, each of which needs to be saved as a list, then save one list, which is a list of lists (where lists are stored as links to arrays):

 my @input = ( [ 'data', 'from', 'first', 'user' ], [ qw(data from second user) ], [ qw(etc etc etc) ], ); 

If you have names associated with each user data, you can use this as a hash key to index the data:

 my %input = ( senthil => [ 'data', 'from', 'first', 'user' ], ether => [ qw(data from second user) ], apu => [ qw(etc etc etc) ], ); 

Refer to the Perl Data Structures Cookbook ( perldoc perldsc ) for more information on choosing the right data structure for the situation and how to determine them.

+12
source share

Creating new named arrays dynamically is almost never a good idea. Mark Dominis, author of a higher-order Perl enlightenment book, wrote three - part series detailing pitfalls.

You have names for these arrays, so put them in a hash:

 sub create_arrays { my($where,$n) = @_; for (1 .. $n) { $where->{"message$_"} = []; } } 

For a quick example showing the structure, the code below

 my $n = @ARGV ? shift : 3; my %hash; create_arrays \%hash, $n; use Data::Dumper; $Data::Dumper::Indent = $Data::Dumper::Terse = 1; print Dumper \%hash; 

exits

  $ ./prog.pl
 {
   'message2' => [],
   'message3' => [],
   'message1' => []
 } 

Specifying a different number of arrays, we get

  $ ./prog.pl 7
 {
   'message2' => [],
   'message6' => [],
   'message5' => [],
   'message4' => [],
   'message3' => [],
   'message1' => [],
   'message7' => []
 } 

The order of the keys looks ridiculous because they are inside a hash, an unordered data structure.

Recall that [] creates a reference to a new anonymous array, therefore, for example, to add values ​​to message2, you must write

 push @{ $hash{"message2"} }, "Hello!"; 

To print it, you must write

 print $hash{"message2"}[0], "\n"; 

Perhaps instead you want to know how long all the arrays are:

 foreach my $i (1 .. $n) { print "message$i: ", scalar @{ $hash{"message$i"} }, "\n"; } 

For more information on how to use links in Perl, see the following documentation:

+3
source share

In compiled languages, variables have no name. The name you see in the code is a unique identifier associated with some numerical offset. In the type identifier message_2 '2' serves only to make it a unique identifier. Anyone can say that you can make three variables: message_125 , message_216 and message_343 . While you can tell what you should invest in them, they work as well as message_1 ...

The "name" of a variable is just so that you save them directly while writing code.

Dynamic languages ​​add features without clearing the character table (s). But a character table is simply an association of a name with a value. Since Perl offers you lists and hashes so cheaply, there is no need to use the software-logistic variable tracking method to provide flexible access at runtime.

Most likely, if you see lists of items @message1 , @message2 , ... - where the elements differ only in their reference order, these names are also good: $message[1] , $message[2] , ....

In addition, since character tables are usually mapped from name to offset (either on the stack or on the heap), this is really not much more than the pair of keys and values ​​that you find in the hash. Thus, hashes work just as well as finding clearer names.

 $h{messages} = []; $h{replies} = []; 

I mean, indeed, if you wanted to, you could store everything you put in the lexical variable in a single hash for the region if you hadn't missed the entry: $h{variable_name} for everything. But you would not get the benefits of implicit visibility control in Perl and in different languages, programmers prefer implicit scope control.

Perl allows for symbolic manipulation, but over the years, dynamic languages ​​have found mixed blessings. But in Perl, you have “perspectives” to give them a name. Since you can determine which code in a compiled language is more likely to be better than a dynamic language, it was determined that more errors use the “compiled perspective” for more things: the way you can see with bias and compiled search behavior provided to you in the Perl core, there is no reason to interfere with the symbol table if you do not need it.

Creating an array dynamically is as simple as: [] . Assigning this place in memory when we do not know how much we want to keep is as simple as:

 push @message, []; 

And creating a list of lists right away is simple:

 @message = map { [] } 1..$num_lists; 

for a specific value in $num_lists .

+2
source share

All Articles