http://www.perlmonks.org?node_id=849583

rdettwyler has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, oh wise ones. I need to create a hash to process several million records (am building competitor to Google (yes, I am a dreamer)). I need to process something like this: file FOO contains single-field records of fruits and vegetables, and file BAR contains the arrays.
$cat foo apple apple pear pear zucchini zucchini eggplant eggplant potato potato $cat bar #!/usr/bin/perl $map{'apple'} = 'fruit'; $map{'pear'} = 'fruit'; $map{'zucchini'} = 'vegetable'; $map{'eggplant'} = 'vegetable'; $map{'potato'} = 'vegetable'; open FILE, "foo" or die$!; my @lines = <FILE>; while (my $line = <FILE>) { chomp; print "$map($_)\n";
Why does this give me nothing? I want to see this:
apple fruit apple fruit pear fruit pear fruit zucchini vegetable zucchini vegetable zucchini vegetable eggplant vegetable eggplant vegetable eggplant vegetable potato vegetable potato vegetable
Thank you so much. Your humble servant, RickyD

Replies are listed 'Best First'.
Re: big job, starting with little script
by zek152 (Pilgrim) on Jul 14, 2010 at 17:43 UTC

    Your problem is that you slurp in the file with "my @lines = <FILE>;" This means that it will never enter the while loop (<FILE> will return undef). Simply take that line out. Also chomp works on $_ but you have $line = <FILE>. The following should work:

    while (<FILE>) { chomp; print "$_ $map{$_}\n"; }

    It looks like you have a missing "}" to close the while loop. Also you should close your FILE filehandle at the end of the program. Its a good habit. Hope that helps.

Re: big job, starting with little script
by Roy Johnson (Monsignor) on Jul 14, 2010 at 17:43 UTC
    You're [also] looking up $_, but reading into $line. Try
    while(<FILE>)
    instead.

    Caution: Contents may have been coded under pressure.
Re: big job, starting with little script
by muba (Priest) on Jul 15, 2010 at 08:02 UTC

    Try to find out where you put the line after reading from the file. Is it in $line (as $line = <FILE>) would suggest?

    Or is it in $_, where you seem to think it is, judging by your use of chomp with no further arguments and thusly implying chomp $_.

    And even more explicitely in the part where you try to print "$map($_)";

    That print statement brings us to another point - you're using parens here, not accolades, or curly braces. Keep an eye out for that kind of typo :)

    The interesting thing is that neither answer is true, as has been pointed out above me, due to you slurping in the entire file before the while loop.

    But I'd like to point out something else as well. I don't mean to discourage you but I think your approach deserves some further thought. Tomato: fruit or veggie?

      But I'd like to point out something else as well. I don't mean to discourage you but I think your approach deserves some further thought. Tomato: fruit or veggie?

      Well, fruit, obviously. To a biologist, anyway. But then, so are zucchini and eggplant, right?

Re: big job, starting with little script
by Generoso (Prior) on Jul 15, 2010 at 23:00 UTC

    You may what to take a look at this.

    #!/usr/bin/perl use strict; use warnings; #open FILE, "foo" or die$!; #my @lines = <FILE>; my %map=(); my $datapos = tell DATA; foreach (grep(/,/, <DATA>)) { chomp; my ($p1,$p2) = split /,/,$_; $map{$p1} = $p2; print '$map{',$p1,'} = \'',$map{$p1},"';\n"; } seek DATA, $datapos, 0; foreach (grep(!/,/, <DATA>)) { chomp; print "$_ $map{$_}\n"; } __DATA__ apple,fruit pear,fruit zucchini,vegetable eggplant,vegetable potato,vegetable apple apple pear pear zucchini zucchini eggplant eggplant potato potato