nmh nmh - 1 year ago 42
Perl Question

Create Perl array without the use of curly brackets so that array is not confined to specific block

I want to maintain an array outside of a block of code. The array that I am interested in is @csv2years. This is currently within a set of curly brackets which contain the code for a

loop. I realise I somehow need to rearrange this so that the curly brackets do not contain the conditions which create the array. I don't know how to specifically reference csv2 without the
for { }

# creates subroutines for discovering year

sub find_year {
my ( $str ) = @_;
my $year;
$year = $1 if( $str =~ /\b((?:19|20)\d\d)\b/ );
return $year


my @csv2 = (); # Creates new empty array @csv2

open CSV2, "<csv2" or die; # Creates the file handle CSV2, inputs the data from csv2 into CVS2

@csv2=<CSV2>; # populates @csv2 array with data from file handle CSV2
close CSV2;

my %csv2hash = (); # Creates empty hash csv2hash

for (@csv2) { # for data in @csv2 array
my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/define the data which is the title

#Indicate that title data will input into csv2hash

$csv2hash{$_} = $title;
#Create a hash for find year of csv2
my %csv2_year = find_year($title);

my @csv2years = keys(%csv2_year);
print "@csv2years\n";

The above code currently prints out @csv2years, but if the
print "@csv2years\n";
is placed outside of the curly brackets, nothing is printed out. How can I rearrange this code so that there is no need for the for loop and/or curly brackets?

Here is the csv2 data:

14564564,1989 the door to the others,546456,47878787
456456445,the Twin Peaks theory project 1979,45454545,45454545
456456445,the Twin Peaks forget that,45454545,45454545
454654564, 1969 hello good world your great ,45456456, 54564654

The output of
print "@csv2years\n";
is :



Answer Source

To answer your immediate need:

my @csv2years;
for ( @csv2 ) {
    push @csv2years, find_year($title);
print "$_\n" for @csv2years;

But there are a ton of improvements that will help you up your Perl-fu. A few of the salient ones are:

  • use strict; use warnings;
  • use a dedicated CSV parser like Text::CSV
  • iterate over the file line by line instead of cramming everything into an array and then loop over each element
  • replace bareword filehandles with lexical ones (open my $fh, ...)
  • assign a default value in case find_year doesn't find a year (empty string, perhaps?)
  • assign the result of find_year to a scalar instead of a hash