Load file into a hash

Load file into a hash

am 06.10.2007 13:04:16 von Bill H

Is there a "perl" way of loading a file directly into a hash instead
of using something like this quick example:

open(FILE,"test.txt");
while()
{
$line = $_;
chop $line;
@dbf = split(/\t/,$line);
$MYHASH{$dbf[0]} = $dbf[1];
}
close(FILE);

where the text file contains entries like this:

NAME0\tsome value
NAME1\tanother value

etc... ?

Bill H

Re: Load file into a hash

am 06.10.2007 13:19:06 von Mark Clements

Bill H wrote:
> Is there a "perl" way of loading a file directly into a hash instead
> of using something like this quick example:
>
> open(FILE,"test.txt");
> while()
> {
> $line = $_;
> chop $line;
> @dbf = split(/\t/,$line);
> $MYHASH{$dbf[0]} = $dbf[1];
> }
> close(FILE);
>
> where the text file contains entries like this:
>
> NAME0\tsome value
> NAME1\tanother value
>

C:\TEMP>cat loadarray.pl
#!perl

use strict;
use warnings;

use Data::Dumper;

my $filename = shift;
open my $fh,"<",$filename or die $!;

my %hash = map { chomp; split /\t/ } <$fh>;

print Dumper(\%hash);

close $fh or die $!;

C:\TEMP>cat data.txt
UK London
France Paris
Italy Rome
USA Washington
Germany Berlin

C:\TEMP>loadarray.pl data.txt
$VAR1 = {
'France' => 'Paris',
'UK' => 'London',
'Italy' => 'Rome',
'Germany' => 'Berlin',
'USA' => 'Washington'
};

C:\TEMP>

Mark

Re: Load file into a hash

am 06.10.2007 13:32:27 von Bill H

On Oct 6, 7:19 am, Mark Clements
wrote:
> Bill H wrote:
> > Is there a "perl" way of loading a file directly into a hash instead
> > of using something like this quick example:
>
> > open(FILE,"test.txt");
> > while()
> > {
> > $line = $_;
> > chop $line;
> > @dbf = split(/\t/,$line);
> > $MYHASH{$dbf[0]} = $dbf[1];
> > }
> > close(FILE);
>
> > where the text file contains entries like this:
>
> > NAME0\tsome value
> > NAME1\tanother value
>
> C:\TEMP>cat loadarray.pl
> #!perl
>
> use strict;
> use warnings;
>
> use Data::Dumper;
>
> my $filename = shift;
> open my $fh,"<",$filename or die $!;
>
> my %hash = map { chomp; split /\t/ } <$fh>;
>
> print Dumper(\%hash);
>
> close $fh or die $!;
>
> C:\TEMP>cat data.txt
> UK London
> France Paris
> Italy Rome
> USA Washington
> Germany Berlin
>
> C:\TEMP>loadarray.pl data.txt
> $VAR1 = {
> 'France' => 'Paris',
> 'UK' => 'London',
> 'Italy' => 'Rome',
> 'Germany' => 'Berlin',
> 'USA' => 'Washington'
> };
>
> C:\TEMP>
>
> Mark- Hide quoted text -
>
> - Show quoted text -

I like that Mark. You basically took everything I had in the while
loop and put it on one line. Nice and neat.

Bill H

Re: Load file into a hash

am 06.10.2007 16:06:18 von nobull67

On Oct 6, 12:19 pm, Mark Clements
wrote:
> my %hash = map { chomp; split /\t/ } <$fh>;

That works but is very fragile - one bad line can screw all your data
from then on.

I prefer (the canonical idiom)

my %hash = map { /(.*?)\t(.*)/ } <$fh>;

This will ignore lines with no "\t" in them. Do something vaguely
reasonable with lines containing more than one "\t". Oh, and it's
shorter too.

Re: Load file into a hash

am 06.10.2007 16:11:56 von nobull67

On Oct 6, 3:06 pm, Brian McCauley wrote:
>
> my %hash = map { /(.*?)\t(.*)/ } <$fh>;

Oh, and since we're slurping the file anyhow we can save a few lines
by using File::Slurp

use File::Slurp;
my %hash = map { /(.*?)\t(.*)/ } read_file('test.txt');

Re: Load file into a hash

am 06.10.2007 22:36:07 von Martijn Lievaart

On Sat, 06 Oct 2007 14:06:18 +0000, Brian McCauley wrote:

> On Oct 6, 12:19 pm, Mark Clements
> wrote:
>> my %hash = map { chomp; split /\t/ } <$fh>;
>
> That works but is very fragile - one bad line can screw all your data
> from then on.
>
> I prefer (the canonical idiom)
>
> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
>
> This will ignore lines with no "\t" in them. Do something vaguely
> reasonable with lines containing more than one "\t". Oh, and it's
> shorter too.

Doesn't that include the newline on any line in the second field?

M4

Re: Load file into a hash

am 06.10.2007 23:36:40 von Tad McClellan

Martijn Lievaart wrote:
> On Sat, 06 Oct 2007 14:06:18 +0000, Brian McCauley wrote:


>> my %hash = map { /(.*?)\t(.*)/ } <$fh>;


> Doesn't that include the newline on any line in the second field?


Which part of the regex can match those newlines?


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: Load file into a hash

am 06.10.2007 23:36:41 von Tad McClellan

Bill H wrote:
> Is there a "perl" way of loading a file directly into a hash instead
> of using something like this quick example:
>
> open(FILE,"test.txt");


You should always, yes *always*, check the return value from open().


> while()
> {
> $line = $_;


If you want it in $line, then put it there, rather than put it
somewhere else and then move it there:

while ( my $line = )


> chop $line;


You should use chomp() to remove newlines.


my %myhash = split /[\t\n]/, do{ local $/; };


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: Load file into a hash

am 07.10.2007 09:53:51 von Martijn Lievaart

On Sat, 06 Oct 2007 21:36:40 +0000, Tad McClellan wrote:

> Martijn Lievaart wrote:
>> On Sat, 06 Oct 2007 14:06:18 +0000, Brian McCauley wrote:
>
>
>>> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
>
>
>> Doesn't that include the newline on any line in the second field?
>
>
> Which part of the regex can match those newlines?

You're right. '.' does not match newlines. Stupid me.

M4

Re: Load file into a hash

am 09.10.2007 23:16:57 von Uri Guttman

>>>>> "BM" == Brian McCauley writes:

BM> On Oct 6, 3:06 pm, Brian McCauley wrote:
>>
>> my %hash = map { /(.*?)\t(.*)/ } <$fh>;

BM> Oh, and since we're slurping the file anyhow we can save a few lines
BM> by using File::Slurp

BM> use File::Slurp;
BM> my %hash = map { /(.*?)\t(.*)/ } read_file('test.txt');

i was going to chime in with slurp as well. :)

i have a better and faster idiom for slurping files into hashes
(untested for typos):

my %hash = read_file('test.txt') =~ /^([^\t]+)\t(.*)$/gm ;

and for most config type files slurping is fast since they are likely
smaller than even the OS's I/O block size which can be 64k or even
256k. there is no savings using perl's i/o system and reading many files
line by line. it is a great teaching technique but it is slower than
slurping in a whole file and parsing it in one regex call (as is
possible in many cases).

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org