Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Array @p is a multiline array, e.g. $p[1] is the second line.

This code will explain what I want:

$size=@p;   # line number of array @p
for($i=0; $i<$size; $i++)
{ 
  @p{$i}= split(/ +/,$p[$i]);
}

I want the result should be like this:

@p0 = $p[0]          first line of array @p goes to array @p0;       
@p1 = $p[1]          second line of array @p goes to array @p1; 
...
...

and so on.

But above code does not work, how can I do it?

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

It is a bad idea to dynamically generate variable names.

I suggest the best solution here is to convert each line in your @p array to an array of fields.

Lets suppose you have a better name for @p, say @lines. Then you can write

my @lines = map [ split ], <$fh>;

to read in all the lines from the file handle $fh and split them on whitespace. The first field of the first line is then $lines[0][0]. The third field of the first line is $lines[0][2] etc.

share|improve this answer
    
Thank you, Borodin....it does work! –  Nurahmad May 21 '13 at 12:22
    
I want to ask another question, I'm very appreciated your help... –  Nurahmad May 21 '13 at 13:00
    
I want to ask another question, I'm very appreciated your help...how can I change several same size arrays to one array like this: my @A = ( [0,0,1,0,1,0,0], [0,0,0,1,0,1,0], [1,0,0,1,0,0,0], [0,1,1,0,0,0,1], [1,0,0,0,0,1,1], [0,1,0,0,1,0,1], [0,0,0,1,1,1,0] ); –  Nurahmad May 21 '13 at 13:06
add comment

First, the syntax @p{$i} accesses the entry with the key $i in a hash %p, and returns it in list context. I don't think you meant that. use strict; use warnings; to get warned about undeclared variables.

You can declare variables with my, e.g. my @p; or my $size = @p;

Creating variable names on the fly is possible, but a bad practice. The good thing is that we don't need to: Perl has references. A reference to an array allows us to nest arrays, e.g.

my @AoA = (
   [1, 2, 3],
   ["a", "b"],
);
say $AoA[0][1]; # 2
say $AoA[1][0]; # a

We can create an array reference by using brackets, e.g. [ @array ], or via the reference operator \:

my @inner_array = (1 .. 3);
my @other_inner = ("a", "b");
my @AoA = (\@inner_array, \@other_array);

But careful: the array references still point to the same array as the original names, thus

push @other_inner, "c";

also updates the entry in @AoA:

say $AoA[1][2]; # c

Translated to your problem this means that you want:

my @pn;
for (@p) { 
  push @pn, [ split /[ ]+/ ];
}

There are many other ways to express this, e.g.

my @pn = map [ split /[ ]+/ ], @p;

or

my @pn;
for my $i ( 0 .. $#p ) {
  $pn[$i] = [ split /[ ]+/, $p[$i] ];
}

To learn more about references, read

share|improve this answer
2  
Most often, a programmer who writes split /[ ]+/ actually wants split ' ' –  Borodin May 21 '13 at 10:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.