Reputation: 11
I'm new to Perl. I'm trying to create a hash from a CSV file.
My CSV data currently looks like this:
id,name,title,rating
123,Andrew,Book 1,3
1221,Abraham,Book 2,4
43,Annie,Book 3,1
I'd like the hash to look like this
$reviews = {
review => [
{
id => [ 123 ],
name => [ Andrew ],
title => [ "Book 1" ],
rating => [ 3 ],
},
{
id => [ 1221 ],
name => [ Abraham ],
title => [ "Book 2" ],
rating => [ 4 ]]
},
{
id => [ 43 ],
name => [ Annie ],
title => [ "Book 3" ],
edition => [ 1 ],
},
]
};
But I'm getting this instead
$VAR1 = {
'123' => {
'name' => 'Andrew',
'title' => 'Book 1',
'id' => '123',
'rating' => '3',
},
'1221' => {
'name' => 'Abraham',
'title' => 'Book 2',
'id' => '1221',
'rating' => '4',
},
'43' => {
'name' => 'Annie',
'title' => 'Book 3',
'id' => '43',
'rating' => '1',
}
};
Here's the code I'm using so far. My CSV is in the output.csv
file and I'm printing the hash in the hashr.txt
file
my %hash;
open (RESULTS, "output.csv")|| die "Can't open output.csv: $!\n";
open (HASHR, "+>hashr.txt")|| die "Can't open hashr.txt: $!\n";
while (<RESULTS>) {
last if /id/
}
my $labels = $_; #save last line to label keys
chop $labels;
while (<RESULTS>) {
chomp;
my @array = split /,/;
my $index = 0;
my %h = map { $_ => $array[$index++]} split( ",", $labels );
#my $key = "review";
#$hash{$key}=\%h;
$hash{ $array[0] } = \%h;
}
print Dumper(\%hash);
print HASHR Dumper(\%hash);
close RESULTS;
Upvotes: 1
Views: 414
Reputation: 35198
Your desired data structure is strange, but the following should get you closer to what you say you want.
You probably could use a refresher of perldsc
to learn more about Complex Data Structures.
use strict;
use warnings;
my $header = <DATA>;
chomp $header;
my @headers = split /,/, $header;
my @records;
while (<DATA>) {
chomp;
my @cols = split /,/;
my %hash;
@hash{@headers} = map [$_], @cols;
push @records, \%hash;
}
use Data::Dump;
dd \@records;
__DATA__
id,name,title,rating
123,Andrew,Book 1,3
1221,Abraham,Book 2,4
43,Annie,Book 3,1
Outputs:
[
{ id => [123], name => ["Andrew"], rating => [3], title => ["Book 1"] },
{ id => [1221], name => ["Abraham"], rating => [4], title => ["Book 2"] },
{ id => [43], name => ["Annie"], rating => [1], title => ["Book 3"] },
]
Upvotes: 1
Reputation: 424
review => [
{
id => [ 123 ],
name => [ Andrew ],
title => [ "Book 1" ],
rating => [ 3 ],
},
'123' => {
'name' => 'Andrew',
'title' => 'Book 1',
'id' => '123',
'rating' => '3',
},
my %h = map { $_ => $array[$index++]} split( ",", $labels );
to
my %h = map { $_ => @{$array[$index++]}} split( ",", $labels );
It's been years since I've touched perl, so that syntax is probably way off but the gist is you'll want to place the values generated into an array, then wrap it all in an array
Upvotes: 0