CSV into hash

17,710

Solution 1

Personally, I like the Text::CSV_XS and IO::File module:

use Text::CSV_XS;
use IO::File;

# Usage example:
my $hash_ref = csv_file_hashref('some_file.csv');

foreach my $key (sort keys %{$hash_ref}){
   print qq{$key: };
   print join q{,}, @{$hash_ref->{$key}};
   print qq{\n};
}

# Implementation:
sub csv_file_hashref {
   my ($filename) = @_;

   my $csv_fh = IO::File->new($filename, 'r');
   my $csv = Text::CSV_XS->new ();

   my %output_hash;

   while(my $colref = $csv->getline ($csv_fh))
   {
      $output_hash{shift @{$colref}} = $colref;
   }

   return \%output_hash;
}

Solution 2

See perlfunc split and perldsc.

  1. Read each line.
  2. Chomp it.
  3. Split it on commas.
  4. Use the first value in the result as the key to your HoA.
  5. The other values become the array.
  6. Store a ref to the array in the hash under the key.
  7. ...
  8. Profit!!!

Make a hash of array references:

Your data structure should look like this:

my %foo = (
    LabelA => [  2, 3,  56, 78, 90 ],
    LabelB => [ 65, 45, 23, 34, 87 ],
    LabelC => [ 67, 34, 56, 67, 98 ],
);

Solution 3

Text::CSV::Hashify

Turn a CSV file into a Perl hash:

# Simple functional interface
use Text::CSV::Hashify;
$hash_ref = hashify('/path/to/file.csv', 'primary_key');

# Object-oriented interface
use Text::CSV::Hashify;
$obj = Text::CSV::Hashify->new( {
        file        => '/path/to/file.csv',
        format      => 'hoh', # hash of hashes, which is default
        key         => 'id',  # needed except when format is 'aoh'
        max_rows    => 20,    # number of records to read; defaults to all
        ... # other key-value pairs possible for Text::CSV
} );

# all records requested
$hash_ref       = $obj->all;
Share:
17,710
RH.
Author by

RH.

Updated on July 08, 2022

Comments

  • RH.
    RH. almost 2 years

    I have a csv with the first column a label followed by comma separated values:

    LabelA,45,56,78,90
    LabelB,56,65,43,32
    LabelC,56,87,98,45
    

    I'd like the first column (LabelA etc) to be the Key in a hash with the numeric values in an array.

    I can read the file into an array or scalar but I'm not sure what to do after that. Suggestions??

    Edit: Ok, so it looks like this assigns the value to a key ..but what about the comma delimited numbers in my example? Where are they going? Are they in %hash ? If so could you maybe dumb down your explanation even further? Thanks.

  • Stef
    Stef about 11 years
    Text::CSV is part of the standard distribution. Hence I choose to use this. Just remove _XS from USE and the constructor.