Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

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?


Comment on Re: Parsing CSV into a hash
Download Code
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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (12)
As of 2015-07-29 06:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (260 votes), past polls