Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perlmonks,
I would like to create a data structure from a csv file.

The sample csv file as follows

Product Name,Product Code,Company1,Company2,Company3 Test One,C001,Y,N,N Test Two,C002,N,N,Y Test Three,C003,Y,Y,N

and I am looking for an output in the below format
{ Company1 => {C001 => Y, C002 => N, C003 => Y}, Company2 => {C001 => N, C002 => N, C003 => Y}, Company3 => {C001 => Y, C002 => Y, C003 => N} }

I tried using Text::CSV_XS module, but not able form a structure as mentioned above
use Text::CSV_XS; my $csv = Text::CSV_XS->new(); open my $FH, "<", "test.csv"; while (<$FH>) { $csv->parse($_); my @fields = $csv->fields;
Is there any CPAN module available to get this structure
Can you please help on this.
Thanks

Replies are listed 'Best First'.
Re: Read data from csv file to a data structure format
by Tux (Canon) on May 18, 2012 at 07:17 UTC

    Like this?

    use v5.14; use warnings; use autodie; use Text::CSV_XS; use Data::Peek; my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 }); my $hdr = $csv->getline (*DATA); $csv->column_names ($hdr); my ($pn, $pc, @comp) = @$hdr; my %comp = map { $_ => {} } @comp; while (my $row = $csv->getline_hr (*DATA)) { my $p = $row->{$pc}; $comp{$_}{$p} = $row->{$_} for @comp; } DDumper \%comp; __END__ Product Name,Product Code,Company1,Company2,Company3 Test One,C001,Y,N,N Test Two,C002,N,N,Y Test Three,C003,Y,Y,N => { Company1 => { C001 => 'Y', C002 => 'N', C003 => 'Y' }, Company2 => { C001 => 'N', C002 => 'N', C003 => 'Y' }, Company3 => { C001 => 'N', C002 => 'Y', C003 => 'N' } }

    Enjoy, Have FUN! H.Merijn
      Thanks a lot for your help.
Re: Read data from csv file to a data structure format
by choroba (Cardinal) on May 18, 2012 at 07:32 UTC
    There is nothing wrong in using Text::CSV_XS so far. The problem is how to restructure the information. You can use the following code as an inspiration:
    #!/usr/bin/perl use warnings; use strict; use feature 'say'; use Text::CSV_XS; use Data::Dumper; my $csv = Text::CSV_XS->new(); $_ = <DATA>; $csv->parse($_); my @companies = $csv->fields; splice @companies, 0, 2; my %hash; while (<DATA>) { $csv->parse($_); my @fields = $csv->fields; for my $i (0 .. $#companies) { $hash{$companies[$i]}{$fields[1]} = $fields[2 + $i]; } } print Dumper \%hash; __DATA__ Product Name,Product Code,Company1,Company2,Company3 Test One,C001,Y,N,N Test Two,C002,N,N,Y Test Three,C003,Y,Y,N