Reputation: 729
I have a CSV file like this:
name,email,salary
a,[email protected],1000
d,[email protected],2000
Now, I need to transform this to an array of hash-maps in Perl, so when I do something like:
table[1]{"email"}
it returns [email protected].
The code I wrote is :
open(DATA, "<$file") or die "Cannot open the file\n";
my @table;
#fetch header line
$line = <DATA>;
my @header = split(',',$line);
#fetch data tuples
while($line = <DATA>)
{
my %map;
my @row = split(',',$line);
for($index = 0; $index <= $#header; $index++)
{
$map{"$header[$index]"} = $row[$index];
}
push(@table, %map);
}
close(DATA);
But I am not getting desired results.. Can u help?? Thanks in advance...
Upvotes: 0
Views: 1196
Reputation: 69314
Something like this perhaps:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my @table;
chomp(my $header = <DATA>);
my @cols = split /,/, $header; # Should really use a real CSV parser here
while (<DATA>) {
chomp;
my %rec;
@rec{@cols} = split /,/;
push @table, \%rec;
}
say $table[1]{email};
__END__
name,email,salary
a,[email protected],1000
d,[email protected],2000
Upvotes: 2
Reputation: 944169
There is no need to reinvent the wheel here. You can do this with the Text::CSV
module.
#!/usr/bin/perl
use strict;
use warnings;
use v5.16;
use Text::CSV;
my $csv = Text::CSV->new;
open my $fh, "<:encoding(utf8)", "data.csv" or die "data.csv: $!";
$csv->column_names( $csv->getline ($fh) );
while (my $row = $csv->getline_hr ($fh)) {
say $row->{email};
}
Upvotes: 5
Reputation: 532033
This line
push(@table, %map)
should be
push(@table, \%map)
You want table
to be a list of hash references; your code adds each key and value in %map
to the list as a separate element.
Upvotes: 6