Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re: Parsing CSV into a hash

by dragonchild (Archbishop)
on Sep 20, 2005 at 02:09 UTC ( #493346=note: print w/ replies, xml ) Need Help??

in reply to Parsing CSV into a hash

Text::xSV was built for exactly this kind of situation. (Why don't people use it more often?!?)
use Text::xSV; my $parser = Text::xSV->new; $parser->open_file( $datafile ); my @headers = $parser->read_header; shift @headers; # Remove the # field. my $user_header = shift @headers; my $data; while ( $parser->get_row ) { my $user = $parser->extract( $user_header ); $data->{ $user }{ @headers } = [ $parser->extract( @headers ) ]; }

Update: Obviously, use tilly's corrections to my suggestion as he wrote the module in question. Plus, he's right. :-)

My criteria for good software:
  1. Does it work?
  2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Replies are listed 'Best First'.
Re^2: Parsing CSV into a hash
by tilly (Archbishop) on Sep 20, 2005 at 08:00 UTC
    use Text::xSV; my $parser = Text::xSV->new( filename=>$datafile, sep=>"\t" ); $parser->read_header; my %data; while (my $row_ref = $parser->get_row) { $data{ $row_ref->[1] } = $parser->extract_hash; }
    The significant changes from your version are:
    1. xSV doesn't default to a tab. You have to tell it that you want that.
    2. You don't need to call open_file - it will do that for you if you pass the filename into the constructor.
    3. The return of read_header cannot be relied on, so don't rely on it.
    4. I'm using the return of get_row directly. Yes, you can mix positional and name-based logic in Text::xSV.
    5. Your slicing logic was buggy. But luckily there is no need to do something that complex.

    UPDATE: A closer reading of the original question shows that the format differs from the obvious. The first row has an extra # in it that is not lined up with the other fields and needs to be discarded. Here is a solution to that variant:

    use Text::xSV; my $parser = Text::xSV->new( filename=>$datafile, sep=>"\t" ); my @headers = $parser->get_row; shift @headers; # Get rid of the unwanted # $parser->bind_fields(@headers); my %data; while (my $row_ref = $parser->get_row) { $data{ $row_ref->[1] } = $parser->extract_hash; }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://493346]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2016-07-27 06:49 GMT
Find Nodes?
    Voting Booth?
    What is your favorite alternate name for a (specific) keyboard key?

    Results (242 votes). Check out past polls.