Reputation: 31
I have a perl-query on saving arrays inside another array. A related query was asked before(How do I add an array ref to the middle of an existing array in Perl?), but I could not find answer to mine, so I am posting it here.
I have 10 text files, each having approximately 100 lines of text. I want to pick all those lines containing the word "important". Script for doing this operation is below. I save all lines containing word "important" in an array. So, from each text file, I get an array. I want to save all those arrays inside another array ?
my @list_of_files = ("input1.txt", "input2.txt","input3.txt"); my $list_of_files = @list_of_files;
for ($file=0, $file<$list_of_files; $files++){
open INPUT_FILE, "$list_of_files[$file]" or die "can't open $file : $!";
my @input = <INPUT_FILE>;
my $size = @input;
for ($num=0; $num<$size; $num++){
if ($input[$num] =~ m/important/) {
push (@sub_array, $output);
}
}
close INPUT_FILE;
push (@main_array, \@sub_array);
}
elements of @sub_array changes every time, so, how do I preserve elements of all sub_arrays ? I would like to have final output as @main_array, which contains 3 elements, each element is an array of elements (lines containing the word "important")
Any help is much appreciated TIA
Upvotes: 3
Views: 2329
Reputation: 9697
I would solve your problem like this:
my @list_of_files = ("input1.txt", "input2.txt", "input3.txt");
my @lines_in_file = (); # target array
for my $file (@list_of_files) {
open(my $in,'<',$file) or die "can't open $file : $!";
my $lines = []; # scalar containing arrayref for important lines
while(my $input = <$in>) {
if($input =~ /important/) {
push @$lines, $input; # push into arrayref
}
}
close $in;
push @lines_in_file, $lines; # push arrayref into main array
}
Few things to note:
[]
construct new arrayref in each iteration. If you reuse @sub_array
in each loop and take reference of it, you end up with many references to same thingUpvotes: 4
Reputation: 477
If you are going to write something in Perl now and then, you will have to understand how references work and how to build complex data structures.
Being a Perl newbie myself, I would recommend you to visit perldoc.perl.org, the manuals section, and work through first three lessons. It would only take you about an hour and a half and you will have an idea on how to solve your problem and others of that kind.
The tutorials are really helpful - brief and practical. You will learn to pass data structures around and iterate on them and whatnot.
For testing, consider using Data::Dumper and print Dumper($var)
to look inside your complicated data structures easily.
Upvotes: 3
Reputation: 69314
I would do it slightly differently to bvr. But his points still stand.
# use qw() to define line with less punctuation
my @list_of_files = qw(input1.txt input2.txt input3.txt);
my @lines_in_file;
foreach my $file (@list_of_files) {
open(my $in, '<', $file) or die "can't open $file : $!";
# declare an array, not a scalar
my @lines;
# idiomatic use of while(<>) puts each record into $_
while (<$in>) {
# /../ works on $_ by default.
# Postfix condition is more readable
push @lines, $_ if /important/;
}
# Take reference to array and push it onto main array
push @lines_in_file, \@lines;
}
Upvotes: 5