0

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?

2 Answers 2

4

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.

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

1 Comment

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] );
3

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

1 Comment

Most often, a programmer who writes split /[ ]+/ actually wants split ' '

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.