CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Read a CSV into hash

 



Crawling_key
Novice

Jun 18, 2009, 12:55 PM

Post #1 of 16 (1805 views)
Read a CSV into hash Can't Post

 
Hi, I have a problem which is probably easy to solved - but not for me - I'm new at Perl.

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


Code
LabelA,2,3,56,78,90 
LabelB,65,45,23,34,87
LabelC,67,34,56,67,98



I'd like the first column 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??

Code



      
    


KevinR
Veteran


Jun 18, 2009, 3:09 PM

Post #2 of 16 (1800 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post

Lets see what code you have written so far.
-------------------------------------------------


Crawling_key
Novice

Jun 18, 2009, 3:45 PM

Post #3 of 16 (1796 views)
Re: [KevinR] Read a CSV into hash [In reply to] Can't Post

Just this:


Code
 
# open files. May fail here if file doesn't exist or is locked
open( IN, "< $infile" ) or die "Unable to read $infile because $!";
open( OUTBAD, "> $outbad" ) or die "Unable to open output $outfile because $!";
open( OUTGOOD, "> $outgood" ) or die "Unable to open output $outfile because $!";





while (<IN>) {

$rec++;
chomp;
$line = $_;
@parsed_line = split(',',$line);

if (m/(\d*,){5}/)
{
$found = $found +1;
print OUTGOOD "$line \n";

}
else
{
print OUTBAD "Rejected Row $rec \n";
};

}


@parsed line contains the data I want to put in a hash (hash of array ?). The first element will be the label. The remaining elements will be the array.

I'll be using this data structure to determine other processing. I will probably end up comparing the key to values from a table.


KevinR
Veteran


Jun 18, 2009, 3:55 PM

Post #4 of 16 (1795 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post

http://stackoverflow.com/questions/1015061/csv-into-hash
-------------------------------------------------


Crawling_key
Novice

Jun 22, 2009, 10:00 AM

Post #5 of 16 (1777 views)
Re: [KevinR] Read a CSV into hash [In reply to] Can't Post

 
My question wasn't answered on stackoverflow. I understand how to get the column labels into a hash but I also need to get the comma delimited integers into the data structure. I may be approaching or describing the problem incorrectly. I need a data structure with the first element equal to the lables and the rest of the elements equal to the integers. Help!


esila
New User

Jun 23, 2009, 8:37 AM

Post #6 of 16 (1764 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post


Quote
I need a data structure with the first element equal to the lables and the rest of the elements equal to the integers


I see how you want the key of your result hash to be the column name (which you say you know how to do). As far as the rest of the elements being integers, how are you looking to store them?

You can store the value as a string with all the integers:

"1,2,3,4"

or as an array:

(1,2,3,4)

Did you want to have your hash values as a string? Or an array? There really is no wrong answer to that question, it's more of a personal preference i.e. what you want to do after having the data structure. Hope this helps!


(This post was edited by esila on Jun 23, 2009, 8:38 AM)


Crawling_key
Novice

Jun 23, 2009, 8:55 AM

Post #7 of 16 (1759 views)
Re: [esila] Read a CSV into hash [In reply to] Can't Post

 
I'd like the values in an array. I think this code accomplishes what I want to do:

Code
 
while (<IN>) {

$rec++;
chomp;
$line = $_;
@parsed_line = split( ',', $line );


$key = shift @parsed_line;
@{ $hash{$key} } = @parsed_line;

}



KevinR
Veteran


Jun 23, 2009, 9:05 AM

Post #8 of 16 (1757 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post


In Reply To
I'd like the values in an array. I think this code accomplishes what I want to do:

Code
 
while (<IN>) {

$rec++;
chomp;
$line = $_;
@parsed_line = split( ',', $line );


$key = shift @parsed_line;
@{ $hash{$key} } = @parsed_line;

}



Well that is basically one of the replies posted on stackoverflow Crazy

But his line needs to be changed:


Code
@{ $hash{$key} } = @parsed_line;


change to:


Code
$hash{$key}  = [@parsed_line];


or:


Code
$hash{$key}  =  \@parsed_line;

-------------------------------------------------


(This post was edited by KevinR on Jun 23, 2009, 9:08 AM)


FishMonger
Veteran / Moderator

Jun 23, 2009, 9:09 AM

Post #9 of 16 (1752 views)
Re: [KevinR] Read a CSV into hash [In reply to] Can't Post


In Reply To

In Reply To
I'd like the values in an array. I think this code accomplishes what I want to do:

Code
 
while (<IN>) {

$rec++;
chomp;
$line = $_;
@parsed_line = split( ',', $line );


$key = shift @parsed_line;
@{ $hash{$key} } = @parsed_line;

}



Well that is basically one of the replies posted on stackoverflow Crazy


And, it's not very well written.

Here's a cleaned up version.

Code
while ( my $line = <IN> ) {  

chomp $line;
my ($key, @parsed_line) = split( /,/, $line );
@{ $hash{$key} } = @parsed_line;

}



KevinR
Veteran


Jun 23, 2009, 9:13 AM

Post #10 of 16 (1750 views)
Re: [FishMonger] Read a CSV into hash [In reply to] Can't Post

Fish,

Its not the exact suggestion, its basically the same though.
-------------------------------------------------


FishMonger
Veteran / Moderator

Jun 23, 2009, 9:35 AM

Post #11 of 16 (1745 views)
Re: [KevinR] Read a CSV into hash [In reply to] Can't Post

Ya, I know.

My intention wasn't to show an alternative method, it was to fix/cleanup the syntax and take out the unneeded stuff. I thought about changing the hash assignment syntax, but didn't.


Crawling_key
Novice

Jun 23, 2009, 9:35 AM

Post #12 of 16 (1744 views)
Re: [KevinR] Read a CSV into hash [In reply to] Can't Post

It looks like all these accomplish the same thing:


Code
@{ $hash{$key} } = @parsed_line;  

$hash{$key} = \@parsed_line;

$hash{$key} = [@parsed_line];


But I don't understand why ...


FishMonger
Veteran / Moderator

Jun 23, 2009, 9:40 AM

Post #13 of 16 (1742 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post

The Perl moto "TMTOWTDI"
http://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it

I almost always try to use the cleanest (not necessarily the shortest) syntax.


KevinR
Veteran


Jun 23, 2009, 10:34 AM

Post #14 of 16 (1737 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post


In Reply To
It looks like all these accomplish the same thing:


Code
@{ $hash{$key} } = @parsed_line;  

$hash{$key} = \@parsed_line;

$hash{$key} = [@parsed_line];


But I don't understand why ...


They don't all do the same thing, but in the limited context of your requirements they will. The first and third line do the same thing, they create a copy of @parsed_line and store it as the value of the hash key (not exactly but you can think of it that way for simplicity sake).

The second line stores a reference to @parsed_line instead of making a new copy of @parsed_line. This is an important concept in the usage of references. A reference to data will change the original data the reference points back to if you make any changes to the reference. The other two ways won't because they created a copy of the data instead of just creating a reference to the data.
-------------------------------------------------


Crawling_key
Novice

Jun 23, 2009, 10:57 AM

Post #15 of 16 (1733 views)
Re: [KevinR] Read a CSV into hash [In reply to] Can't Post

 
Pointers. Neat.

Can you explain what the []s are doing here:

$hash{$key} = [@parsed_line];

Also, why would this not work and what would it generate?

$hash{$key} = @parsed_line;

Thanks.


KevinR
Veteran


Jun 23, 2009, 11:06 AM

Post #16 of 16 (1730 views)
Re: [Crawling_key] Read a CSV into hash [In reply to] Can't Post


In Reply To
Pointers. Neat.

Can you explain what the []s are doing here:

$hash{$key} = [@parsed_line];

Also, why would this not work and what would it generate?

$hash{$key} = @parsed_line;

Thanks.


The square brackets are creating an anonymous array and storing the values of @parsed_line in the anonymous array. This makes a copy of the array instead of a reference back to the array.

The other example you have is the same as this:


Code
$length = @array;


whenever you assign an array to a scalar (which the hash key is) you get the length of the array. Perl has two contexts, list and scalar, and you have to be aware that using one context or the other changes how some things work in perl.
-------------------------------------------------

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives